diff --git a/alib2data/src/alphabet/SymbolBase.h b/alib2data/src/alphabet/SymbolBase.h index ce062e65ae78abf67d4dc4604bb850c0647d02a9..18027e6451d69f9f2e1fcfb60010a0aee86982a4 100644 --- a/alib2data/src/alphabet/SymbolBase.h +++ b/alib2data/src/alphabet/SymbolBase.h @@ -13,7 +13,9 @@ namespace alphabet { -typedef std::acceptor_base< +class SymbolBase; + +typedef std::acceptor_base<SymbolBase, LabeledSymbol, BlankSymbol, BottomOfTheStackSymbol, EndSymbol > VisitableSymbolBase; diff --git a/alib2data/src/automaton/AutomatonBase.h b/alib2data/src/automaton/AutomatonBase.h index 5442d018b1a6566e79fae079c0d9549e9c06b960..ff3d4c3249d4d49edf9efd8b5ed16a1272709fc8 100644 --- a/alib2data/src/automaton/AutomatonBase.h +++ b/alib2data/src/automaton/AutomatonBase.h @@ -14,7 +14,9 @@ namespace automaton { -typedef std::acceptor_base< +class AutomatonBase; + +typedef std::acceptor_base<AutomatonBase, automaton::DFA, automaton::NFA, automaton::MultiInitialStateNFA, automaton::EpsilonNFA, automaton::CompactNFA, automaton::ExtendedNFA, automaton::DPDA, automaton::SinglePopDPDA, automaton::InputDrivenNPDA, automaton::VisiblyPushdownDPDA, automaton::VisiblyPushdownNPDA, automaton::RealTimeHeightDeterministicDPDA, automaton::RealTimeHeightDeterministicNPDA, automaton::NPDA, automaton::SinglePopNPDA, automaton::OneTapeDTM > VisitableAutomatonBase; diff --git a/alib2data/src/automaton/FSM/CompactNFA.h b/alib2data/src/automaton/FSM/CompactNFA.h index 97941daacb196266c8a23b27b8ad146bb92fc0e8..5a8a23a227ac9bb370fa698764ecfac52ba92942 100644 --- a/alib2data/src/automaton/FSM/CompactNFA.h +++ b/alib2data/src/automaton/FSM/CompactNFA.h @@ -13,6 +13,10 @@ #include "../common/SingleInitialState.h" #include "../common/InputAlphabet.h" #include "../../string/LinearString.h" +#include "EpsilonNFA.h" +#include "MultiInitialStateNFA.h" +#include "NFA.h" +#include "DFA.h" namespace automaton { diff --git a/alib2data/src/automaton/FSM/EpsilonNFA.h b/alib2data/src/automaton/FSM/EpsilonNFA.h index ad4f323aa83271fd14e3a827e1c43a9d819d08ea..348dead1da57cbe7a44441127aebdbdff85d2975 100644 --- a/alib2data/src/automaton/FSM/EpsilonNFA.h +++ b/alib2data/src/automaton/FSM/EpsilonNFA.h @@ -15,6 +15,9 @@ #include "../common/InputAlphabet.h" #include "../../alphabet/Symbol.h" #include "../../string/Epsilon.h" +#include "MultiInitialStateNFA.h" +#include "NFA.h" +#include "DFA.h" namespace automaton { diff --git a/alib2data/src/automaton/FSM/ExtendedNFA.h b/alib2data/src/automaton/FSM/ExtendedNFA.h index 54db04aca6e5bec7d587b73bb44ac17dfbd873ff..6703e34da19ac305a35047a9222c76f68960b4aa 100644 --- a/alib2data/src/automaton/FSM/ExtendedNFA.h +++ b/alib2data/src/automaton/FSM/ExtendedNFA.h @@ -13,6 +13,11 @@ #include "../common/SingleInitialState.h" #include "../common/InputAlphabet.h" #include "../../regexp/RegExp.h" +#include "CompactNFA.h" +#include "EpsilonNFA.h" +#include "MultiInitialStateNFA.h" +#include "NFA.h" +#include "DFA.h" namespace automaton { diff --git a/alib2data/src/automaton/FSM/MultiInitialStateNFA.h b/alib2data/src/automaton/FSM/MultiInitialStateNFA.h index 830f166f3645ebbecc253bd0a6662dccd00bb43b..e104ce8a511c725dd6096108c88c2dbf0949b7c6 100644 --- a/alib2data/src/automaton/FSM/MultiInitialStateNFA.h +++ b/alib2data/src/automaton/FSM/MultiInitialStateNFA.h @@ -14,6 +14,8 @@ #include "../common/MultiInitialStates.h" #include "../common/InputAlphabet.h" #include "../../alphabet/Symbol.h" +#include "NFA.h" +#include "DFA.h" namespace automaton { diff --git a/alib2data/src/automaton/FSM/NFA.cpp b/alib2data/src/automaton/FSM/NFA.cpp index f5ca944190775e3fd11b485b8c9b3c57782567c0..f92be7d733b9e850a894a0091be3c0bd37164ba9 100644 --- a/alib2data/src/automaton/FSM/NFA.cpp +++ b/alib2data/src/automaton/FSM/NFA.cpp @@ -6,7 +6,6 @@ */ #include "NFA.h" -#include "DFA.h" #include "../AutomatonException.h" #include <ostream> #include <sstream> diff --git a/alib2data/src/automaton/FSM/NFA.h b/alib2data/src/automaton/FSM/NFA.h index 24af23d31d5ef6e50b9c9a41c5edef67c169edc6..880ac3d3fda4c80eac8c2df81ade7f438dc6a3cb 100644 --- a/alib2data/src/automaton/FSM/NFA.h +++ b/alib2data/src/automaton/FSM/NFA.h @@ -15,6 +15,8 @@ #include "../common/InputAlphabet.h" #include "../../alphabet/Symbol.h" +#include "DFA.h" + namespace automaton { /** diff --git a/alib2data/src/container/ContainerBase.h b/alib2data/src/container/ContainerBase.h index c9eb75c43d47ca37c466162ab1e515a571e60912..66c2ab8905f9a30ff2aa11bc8aae3197ee607b11 100644 --- a/alib2data/src/container/ContainerBase.h +++ b/alib2data/src/container/ContainerBase.h @@ -13,7 +13,9 @@ namespace container { -typedef std::acceptor_base< +class ContainerBase; + +typedef std::acceptor_base<ContainerBase, container::ObjectsSet, container::ObjectsVector, container::ObjectsPair, diff --git a/alib2data/src/grammar/GrammarBase.h b/alib2data/src/grammar/GrammarBase.h index 502ac204be4bb18e9288cda7073a356ec8782eca..9ad26cb132a22477edd1c2dfb9d6c146baa246b8 100644 --- a/alib2data/src/grammar/GrammarBase.h +++ b/alib2data/src/grammar/GrammarBase.h @@ -14,7 +14,9 @@ namespace grammar { -typedef std::acceptor_base< +class GrammarBase; + +typedef std::acceptor_base<GrammarBase, grammar::LeftLG, grammar::LeftRG, grammar::RightLG, grammar::RightRG, grammar::LG, grammar::CFG, grammar::EpsilonFreeCFG, grammar::CNF, grammar::GNF, grammar::CSG, grammar::NonContractingGrammar, grammar::ContextPreservingUnrestrictedGrammar, grammar::UnrestrictedGrammar > VisitableGrammarBase; diff --git a/alib2data/src/label/LabelBase.h b/alib2data/src/label/LabelBase.h index 58df68b6728c00e3f109d3b7a51194b67ce88938..1fea94675d052263aa48215a5935623e21cce3ec 100644 --- a/alib2data/src/label/LabelBase.h +++ b/alib2data/src/label/LabelBase.h @@ -13,7 +13,9 @@ namespace label { -typedef std::acceptor_base< +class LabelBase; + +typedef std::acceptor_base<LabelBase, label::PrimitiveLabel, label::HexavigesimalLabel, label::ObjectLabel, label::LabelSetLabel, label::LabelPairLabel > VisitableLabelBase; diff --git a/alib2data/src/object/ObjectBase.h b/alib2data/src/object/ObjectBase.h index 87acf1f8b27163e061116bdf9159e32485435d6b..0a99bd83e8ccc3a30a4869c895e515ecb6749650 100644 --- a/alib2data/src/object/ObjectBase.h +++ b/alib2data/src/object/ObjectBase.h @@ -115,7 +115,9 @@ class Character; namespace alib { -typedef std::acceptor_base< +class ObjectBase; + +typedef std::acceptor_base<ObjectBase, Void, exception::AlibException, automaton::DFA, automaton::NFA, automaton::MultiInitialStateNFA, automaton::EpsilonNFA, automaton::CompactNFA, automaton::ExtendedNFA, automaton::DPDA, automaton::SinglePopDPDA, automaton::InputDrivenNPDA, automaton::VisiblyPushdownDPDA, automaton::VisiblyPushdownNPDA, automaton::RealTimeHeightDeterministicDPDA, automaton::RealTimeHeightDeterministicNPDA, automaton::NPDA, automaton::SinglePopNPDA, automaton::OneTapeDTM, diff --git a/alib2data/src/primitive/PrimitiveBase.h b/alib2data/src/primitive/PrimitiveBase.h index 33866ca880fb1a088cbc3e7c17c50b494379e889..7a2dfe9a5fc640df7bce67e3edd4fa1cb7864f68 100644 --- a/alib2data/src/primitive/PrimitiveBase.h +++ b/alib2data/src/primitive/PrimitiveBase.h @@ -13,7 +13,9 @@ namespace primitive { -typedef std::acceptor_base< +class PrimitiveBase; + +typedef std::acceptor_base<PrimitiveBase, primitive::String, primitive::Integer, primitive::Character > VisitablePrimitiveBase; diff --git a/alib2data/src/regexp/RegExpBase.h b/alib2data/src/regexp/RegExpBase.h index db3ae48d4f0ff45ab4641c96e3c62c4d6facc4ed..639c6f52a703e6e2fff69b5afd8ea3a36b2da3aa 100644 --- a/alib2data/src/regexp/RegExpBase.h +++ b/alib2data/src/regexp/RegExpBase.h @@ -13,7 +13,9 @@ namespace regexp { -typedef std::acceptor_base< +class RegExpBase; + +typedef std::acceptor_base<RegExpBase, UnboundedRegExp, FormalRegExp > VisitableRegExpBase; diff --git a/alib2data/src/regexp/formal/FormalRegExpElement.h b/alib2data/src/regexp/formal/FormalRegExpElement.h index ac25ee31840c6a913e4823548b281feeccd8fd2f..e02d2d5382d34ad67c6a5c2828c9696326256b05 100644 --- a/alib2data/src/regexp/formal/FormalRegExpElement.h +++ b/alib2data/src/regexp/formal/FormalRegExpElement.h @@ -25,11 +25,12 @@ class FormalRegExpEmpty; class FormalRegExpEpsilon; class UnboundedRegExpElement; +class FormalRegExpElement; /** * Abstract class representing element in the regular expression. Can be operator or symbol. */ -class FormalRegExpElement : public std::acceptor_base<FormalRegExpAlternation, FormalRegExpConcatenation, FormalRegExpIteration, FormalRegExpSymbol, FormalRegExpEmpty, FormalRegExpEpsilon> { +class FormalRegExpElement : public std::acceptor_base<FormalRegExpElement, FormalRegExpAlternation, FormalRegExpConcatenation, FormalRegExpIteration, FormalRegExpSymbol, FormalRegExpEmpty, FormalRegExpEpsilon> { protected: /* * Parent regexp contanining this instance of RegExpElement diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpElement.h b/alib2data/src/regexp/unbounded/UnboundedRegExpElement.h index c0ce6c8f9f13d32f1a31f3de3d8f1bf68967c6bb..9d6ee37cec27443f46a389efb3d827a8a6ac96e6 100644 --- a/alib2data/src/regexp/unbounded/UnboundedRegExpElement.h +++ b/alib2data/src/regexp/unbounded/UnboundedRegExpElement.h @@ -25,11 +25,12 @@ class UnboundedRegExpEmpty; class UnboundedRegExpEpsilon; class FormalRegExpElement; +class UnboundedRegExpElement; /** * Abstract class representing element in the regular expression. Can be operator or symbol. */ -class UnboundedRegExpElement : public std::acceptor_base<UnboundedRegExpAlternation, UnboundedRegExpConcatenation, UnboundedRegExpIteration, UnboundedRegExpSymbol, UnboundedRegExpEmpty, UnboundedRegExpEpsilon> { +class UnboundedRegExpElement : public std::acceptor_base<UnboundedRegExpElement, UnboundedRegExpAlternation, UnboundedRegExpConcatenation, UnboundedRegExpIteration, UnboundedRegExpSymbol, UnboundedRegExpEmpty, UnboundedRegExpEpsilon> { protected: /** * Parent regexp contanining this instance of RegExpElement diff --git a/alib2data/src/std/visitor.hpp b/alib2data/src/std/visitor.hpp index e70671a1fc2fac16064feca4a5ba84503852cd53..d65eecdfa82fa22f394bfb35f8bb092fe1fcb9e6 100644 --- a/alib2data/src/std/visitor.hpp +++ b/alib2data/src/std/visitor.hpp @@ -2,8 +2,8 @@ * Visitor.h * * Created on: Apr 05, 2014 - * Author: Andrew Durward - * Modified: Jan Travnicek + * Author: Andrew Durward + * Modified: Jan Travnicek */ #ifndef VISITOR_H_ @@ -21,17 +21,17 @@ class visitor; template<typename T> class visitor<T> { public: - virtual void Visit(void*, const T &) = 0; + virtual void Visit(void*, const T &) = 0; }; // specialization for multiple types template<typename T, typename... Types> class visitor<T, Types...> : public visitor<Types...> { public: - // promote the function(s) from the base class - using visitor<Types...>::Visit; + // promote the function(s) from the base class + using visitor<Types...>::Visit; - virtual void Visit(void*, const T &) = 0; + virtual void Visit(void*, const T &) = 0; }; // Visitor template declaration @@ -42,40 +42,126 @@ class const_visitor; template<typename T> class const_visitor<T> { public: - virtual void Visit(void*, const T &) const = 0; + virtual void Visit(void*, const T &) const = 0; }; // specialization for multiple types template<typename T, typename... Types> class const_visitor<T, Types...> : public const_visitor<Types...> { public: - // promote the function(s) from the base class - using const_visitor<Types...>::Visit; + // promote the function(s) from the base class + using const_visitor<Types...>::Visit; - virtual void Visit(void*, const T &) const = 0; + virtual void Visit(void*, const T &) const = 0; }; template<typename... Types> +class const_promoting_helper; + +template<typename Tested, typename... Other> +struct const_promoting_helper<Tested, Other...> { + + template<class Desired, class Base, class TargetVisitor, + typename std::enable_if< std::is_constructible<Desired, Tested>::value >::type* = nullptr > + inline static bool tryPromote(void* userData, const Desired& first, const Base& second, const TargetVisitor& visitor) { + if(dynamic_cast<const Tested*>(&second)) { + visitor.Visit(userData, first, Desired(dynamic_cast<const Tested&>(second))); + return true; + } else { + return const_promoting_helper<Other...>::tryPromote(userData, first, second, visitor); + } + } + + template<class Desired, class Base, class TargetVisitor, + typename std::enable_if< ! std::is_constructible<Desired, Tested>::value >::type* = nullptr > + inline static bool tryPromote(void* userData, const Desired& first, const Base& second, const TargetVisitor& visitor) { + return const_promoting_helper<Other...>::tryPromote(userData, first, second, visitor); + } +}; + +template<> struct const_promoting_helper<> { + template<class Desired, class Base, class TargetVisitor> + inline static bool tryPromote(void*, const Desired&, const Base&, const TargetVisitor&) { return false; } +}; + +// Visitor template declaration +template<typename... Types> +class const_promoting_visitor; + +// specialization for single type +template<typename T> +class const_promoting_visitor<T> { +public: + virtual void Visit(void*, const T &, const T&) const = 0; + + template<typename R, typename promoting_helper_type> + bool Visit1(void* userData, const T& first, const R& second) const { + return promoting_helper_type::tryPromote( userData, first, second, *this ); + } +}; + +// specialization for multiple types +template<typename T, typename... Types> +class const_promoting_visitor<T, Types...> : public const_promoting_visitor<Types...> { +public: + // promote the function(s) from the base class + using const_promoting_visitor<Types...>::Visit; + using const_promoting_visitor<Types...>::Visit1; + + virtual void Visit(void*, const T &, const T&) const = 0; + + template<typename R, typename promoting_helper_type> + bool Visit1(void* userData, const T& first, const R& second) const { + return promoting_helper_type::tryPromote( userData, first, second, *this ); + } +}; + +template<typename T, typename... Types> class acceptor_base { public: - typedef visitor<Types...> visitor_type; - typedef const_visitor<Types...> const_visitor_type; + typedef visitor<Types...> visitor_type; + + typedef const_visitor<Types...> const_visitor_type; - virtual void Accept(void* userData, visitor<Types...>& visitor) const = 0; - virtual void Accept(void* userData, const const_visitor<Types...>& visitor) const = 0; + typedef const_promoting_visitor<Types...> const_promoting_visitor_type; + typedef const_promoting_helper<Types...> const_promoting_helper_type; + typedef T base_type; + + virtual void Accept(void* userData, visitor<Types...>& visitor) const = 0; + + virtual void Accept(void* userData, const const_visitor<Types...>& visitor) const = 0; + + virtual bool Accept(void* userData, const T& other, const const_promoting_visitor<Types...>& visitor) const = 0; }; -template<typename Derived, typename Visitor, typename Base> +template<typename Derived, typename AcceptorBase, typename Base> class acceptor : public Base { public: - virtual void Accept(void* userData, typename Visitor::visitor_type& visitor) const { - visitor.Visit(userData, static_cast<const Derived&>(*this)); - } - virtual void Accept(void* userData, const typename Visitor::const_visitor_type& visitor) const { - visitor.Visit(userData, static_cast<const Derived&>(*this)); - } + virtual void Accept(void* userData, typename AcceptorBase::visitor_type& visitor) const { + visitor.Visit(userData, static_cast<const Derived&>(*this)); + } + virtual void Accept(void* userData, const typename AcceptorBase::const_visitor_type& visitor) const { + visitor.Visit(userData, static_cast<const Derived&>(*this)); + } + + virtual bool Accept(void* userData, const typename AcceptorBase::base_type& other, const typename AcceptorBase::const_promoting_visitor_type& visitor) const { + return visitor.template Visit1<typename AcceptorBase::base_type, typename AcceptorBase::const_promoting_helper_type>(userData, static_cast<const Derived&>(*this), other); + } }; + +template<class T, class R> +void Accept(void* userData, const T& first, const T& second, const R& visitor) { + bool res; + res = first.Accept(userData, second, visitor); + if(res) return; + + res = second.Accept(userData, first, visitor); + if(res) return; + + throw std::logic_error("cant promote parameters"); +} + } /* namespace std */ #endif /* VISITOR_H_ */ diff --git a/alib2data/src/string/StringBase.h b/alib2data/src/string/StringBase.h index 64ef5419e6d3b03b6cfe014901241ac784d9157f..de7461bcde6a07e06b4d00002de01830cc9b768a 100644 --- a/alib2data/src/string/StringBase.h +++ b/alib2data/src/string/StringBase.h @@ -13,7 +13,9 @@ namespace string { -typedef std::acceptor_base< +class StringBase; + +typedef std::acceptor_base<StringBase, string::Epsilon, string::LinearString, string::CyclicString > VisitableStringBase; @@ -27,7 +29,6 @@ public: virtual StringBase* clone() const = 0; virtual StringBase* plunder() && = 0; - }; } /* namespace string */ diff --git a/alib2data/test-src/std/StdVisitorTest.cpp b/alib2data/test-src/std/StdVisitorTest.cpp new file mode 100644 index 0000000000000000000000000000000000000000..314c3d0e13da0856f2aa2423a11e3708872bcaf0 --- /dev/null +++ b/alib2data/test-src/std/StdVisitorTest.cpp @@ -0,0 +1,233 @@ +#include "StdVisitorTest.h" +#include "std/visitor.hpp" +#include "common/base.hpp" +#include <set> +#include <string> + +CPPUNIT_TEST_SUITE_REGISTRATION( StdVisitorTest ); + +void StdVisitorTest::setUp() { +} + +void StdVisitorTest::tearDown() { +} + +class Tmp1; +class Tmp2; +class Tmp3; + +class TmpBase; + +typedef std::acceptor_base<TmpBase, + Tmp1, Tmp2, Tmp3 + > VisitableTmpBase; + +class TmpBase : + public alib::base< + TmpBase, + Tmp1, Tmp2, Tmp3 + >, public VisitableTmpBase { +}; + +class Tmp1 : public std::acceptor<Tmp1, VisitableTmpBase, TmpBase> { + int data; +public: + Tmp1(int data) : data(data) { + + } + + TmpBase* clone() const { + return new Tmp1(*this); + } + + TmpBase* plunder() && { + return new Tmp1(*this); + } + + virtual bool operator<(const TmpBase& other) const { + return other > *this; + } + + virtual bool operator==(const TmpBase& other) const { + return other == *this; + } + + virtual bool operator>(const TmpBase& other) const { + return other < *this; + } + + virtual bool operator==(const Tmp1& other) const { + return this->data == other.data; + } + + virtual bool operator<(const Tmp1& other) const { + return this->data < other.data; + } + + virtual void operator>>(std::ostream& os) const { + os << "Tmp1(" << data << ")"; + } + + virtual operator std::string() const { + return "Tmp1(" + std::to_string(data) + ")"; + } + + virtual int selfTypeId() const { + return typeId(*this); + } + + int getData() const { + return data; + } + +}; + +class Tmp2 : public std::acceptor<Tmp2, VisitableTmpBase, TmpBase> { + double data; +public: + Tmp2(double data) : data(data) { + + } + + Tmp2(const Tmp1& other) : data(other.getData()) { + + } + + TmpBase* clone() const { + return new Tmp2(*this); + } + + TmpBase* plunder() && { + return new Tmp2(*this); + } + + virtual bool operator<(const TmpBase& other) const { + return other > *this; + } + + virtual bool operator==(const TmpBase& other) const { + return other == *this; + } + + virtual bool operator>(const TmpBase& other) const { + return other < *this; + } + + virtual bool operator==(const Tmp2& other) const { + return this->data == other.data; + } + + virtual bool operator<(const Tmp2& other) const { + return this->data < other.data; + } + + virtual void operator>>(std::ostream& os) const { + os << "Tmp2(" << data << ")"; + } + + virtual operator std::string() const { + return "Tmp2(" + std::to_string(data) + ")"; + } + + virtual int selfTypeId() const { + return typeId(*this); + } + + double getData() const { + return data; + } + +}; + +class Tmp3 : public std::acceptor<Tmp3, VisitableTmpBase, TmpBase> { + std::string data; +public: + Tmp3(const std::string& data) : data(data) { + + } + + Tmp3(const Tmp1& other) : data(std::to_string(other.getData())) { + + } + + Tmp3(const Tmp2& other) : data(std::to_string(other.getData())) { + + } + + TmpBase* clone() const { + return new Tmp3(*this); + } + + TmpBase* plunder() && { + return new Tmp3(*this); + } + + virtual bool operator<(const TmpBase& other) const { + return other > *this; + } + + virtual bool operator==(const TmpBase& other) const { + return other == *this; + } + + virtual bool operator>(const TmpBase& other) const { + return other < *this; + } + + virtual bool operator==(const Tmp3& other) const { + return this->data == other.data; + } + + virtual bool operator<(const Tmp3& other) const { + return this->data < other.data; + } + + virtual void operator>>(std::ostream& os) const { + os << "Tmp3(" << data << ")"; + } + + virtual operator std::string() const { + return "Tmp3(" + data + ")"; + } + + virtual int selfTypeId() const { + return typeId(*this); + } + + const std::string& getData() const { + return data; + } + +}; + +class TmpVisitor : public VisitableTmpBase::const_promoting_visitor_type { + void Visit(void* userData, const Tmp1& first, const Tmp1& second) const { + int& data = *((int*) userData); + data = 1; + std::cout << first << " " << second << std::endl; + } + + void Visit(void* userData, const Tmp2& first, const Tmp2& second) const { + int& data = *((int*) userData); + data = 2; + std::cout << first << " " << second << std::endl; + } + + void Visit(void* userData, const Tmp3& first, const Tmp3& second) const { + int& data = *((int*) userData); + data = 3; + std::cout << first << " " << second << std::endl; + } +}; + +void StdVisitorTest::testPromoteVisitor() { + TmpVisitor visitor; + + Tmp1 tmp1(2); + Tmp3 tmp3("3"); + + int a = 0; + Accept((void*) &a, (TmpBase&) tmp1, (TmpBase&) tmp3, visitor); + + CPPUNIT_ASSERT(a == 3); +} diff --git a/alib2data/test-src/std/StdVisitorTest.h b/alib2data/test-src/std/StdVisitorTest.h new file mode 100644 index 0000000000000000000000000000000000000000..da75d57781b8b15d9c95415052ec1b8d8db022ab --- /dev/null +++ b/alib2data/test-src/std/StdVisitorTest.h @@ -0,0 +1,19 @@ +#ifndef VISITOR_TEST_H_ +#define VISITOR_TEST_H_ + +#include <cppunit/extensions/HelperMacros.h> + +class StdVisitorTest : public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE( StdVisitorTest ); + CPPUNIT_TEST( testPromoteVisitor ); + CPPUNIT_TEST_SUITE_END(); + +public: + void setUp(); + void tearDown(); + + void testPromoteVisitor(); +}; + +#endif // VISITOR_TEST_H_