mirror of
https://github.com/ETLCPP/etl.git
synced 2026-04-30 19:09:10 +08:00
Addedetl::type~_list to message_router, observer, visitor
# Conflicts: # include/etl/observer.h # test/vs2022/etl.vcxproj.filters
This commit is contained in:
parent
1c0d7a87de
commit
c67c617d8c
@ -64,6 +64,7 @@ SOFTWARE.
|
||||
#include "placement_new.h"
|
||||
#include "successor.h"
|
||||
#include "type_traits.h"
|
||||
#include "type_list.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
@ -410,7 +411,8 @@ namespace etl
|
||||
{
|
||||
public:
|
||||
|
||||
typedef etl::message_packet<TMessageTypes...> message_packet;
|
||||
using message_packet = etl::message_packet<TMessageTypes...>;
|
||||
using type_list = etl::type_list<TMessageTypes...>;
|
||||
|
||||
//**********************************************
|
||||
message_router()
|
||||
@ -566,6 +568,10 @@ namespace etl
|
||||
|
||||
typedef etl::message_packet<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> message_packet;
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
using type_list = etl::type_list<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>;
|
||||
#endif
|
||||
|
||||
//**********************************************
|
||||
message_router(etl::message_router_id_t id_)
|
||||
: imessage_router(id_)
|
||||
@ -717,6 +723,10 @@ namespace etl
|
||||
|
||||
typedef etl::message_packet<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> message_packet;
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
using type_list = etl::type_list<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>;
|
||||
#endif
|
||||
|
||||
//**********************************************
|
||||
message_router(etl::message_router_id_t id_)
|
||||
: imessage_router(id_)
|
||||
@ -868,6 +878,10 @@ namespace etl
|
||||
|
||||
typedef etl::message_packet<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> message_packet;
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
using type_list = etl::type_list<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>;
|
||||
#endif
|
||||
|
||||
//**********************************************
|
||||
message_router(etl::message_router_id_t id_)
|
||||
: imessage_router(id_)
|
||||
@ -1018,6 +1032,10 @@ namespace etl
|
||||
|
||||
typedef etl::message_packet<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> message_packet;
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
using type_list = etl::type_list<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>;
|
||||
#endif
|
||||
|
||||
//**********************************************
|
||||
message_router(etl::message_router_id_t id_)
|
||||
: imessage_router(id_)
|
||||
@ -1166,6 +1184,10 @@ namespace etl
|
||||
|
||||
typedef etl::message_packet<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> message_packet;
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
using type_list = etl::type_list<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>;
|
||||
#endif
|
||||
|
||||
//**********************************************
|
||||
message_router(etl::message_router_id_t id_)
|
||||
: imessage_router(id_)
|
||||
@ -1313,6 +1335,10 @@ namespace etl
|
||||
|
||||
typedef etl::message_packet<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> message_packet;
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
using type_list = etl::type_list<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>;
|
||||
#endif
|
||||
|
||||
//**********************************************
|
||||
message_router(etl::message_router_id_t id_)
|
||||
: imessage_router(id_)
|
||||
@ -1459,6 +1485,10 @@ namespace etl
|
||||
|
||||
typedef etl::message_packet<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> message_packet;
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
using type_list = etl::type_list<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>;
|
||||
#endif
|
||||
|
||||
//**********************************************
|
||||
message_router(etl::message_router_id_t id_)
|
||||
: imessage_router(id_)
|
||||
@ -1604,6 +1634,10 @@ namespace etl
|
||||
|
||||
typedef etl::message_packet<T1, T2, T3, T4, T5, T6, T7, T8, T9> message_packet;
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
using type_list = etl::type_list<T1, T2, T3, T4, T5, T6, T7, T8, T9>;
|
||||
#endif
|
||||
|
||||
//**********************************************
|
||||
message_router(etl::message_router_id_t id_)
|
||||
: imessage_router(id_)
|
||||
@ -1747,6 +1781,10 @@ namespace etl
|
||||
|
||||
typedef etl::message_packet<T1, T2, T3, T4, T5, T6, T7, T8> message_packet;
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
using type_list = etl::type_list<T1, T2, T3, T4, T5, T6, T7, T8>;
|
||||
#endif
|
||||
|
||||
//**********************************************
|
||||
message_router(etl::message_router_id_t id_)
|
||||
: imessage_router(id_)
|
||||
@ -1889,6 +1927,10 @@ namespace etl
|
||||
|
||||
typedef etl::message_packet<T1, T2, T3, T4, T5, T6, T7> message_packet;
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
using type_list = etl::type_list<T1, T2, T3, T4, T5, T6, T7>;
|
||||
#endif
|
||||
|
||||
//**********************************************
|
||||
message_router(etl::message_router_id_t id_)
|
||||
: imessage_router(id_)
|
||||
@ -2029,6 +2071,10 @@ namespace etl
|
||||
|
||||
typedef etl::message_packet<T1, T2, T3, T4, T5, T6> message_packet;
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
using type_list = etl::type_list<T1, T2, T3, T4, T5, T6>;
|
||||
#endif
|
||||
|
||||
//**********************************************
|
||||
message_router(etl::message_router_id_t id_)
|
||||
: imessage_router(id_)
|
||||
@ -2168,6 +2214,10 @@ namespace etl
|
||||
|
||||
typedef etl::message_packet<T1, T2, T3, T4, T5> message_packet;
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
using type_list = etl::type_list<T1, T2, T3, T4, T5>;
|
||||
#endif
|
||||
|
||||
//**********************************************
|
||||
message_router(etl::message_router_id_t id_)
|
||||
: imessage_router(id_)
|
||||
@ -2305,6 +2355,10 @@ namespace etl
|
||||
|
||||
typedef etl::message_packet<T1, T2, T3, T4> message_packet;
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
using type_list = etl::type_list<T1, T2, T3, T4>;
|
||||
#endif
|
||||
|
||||
//**********************************************
|
||||
message_router(etl::message_router_id_t id_)
|
||||
: imessage_router(id_)
|
||||
@ -2441,6 +2495,10 @@ namespace etl
|
||||
|
||||
typedef etl::message_packet<T1, T2, T3> message_packet;
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
using type_list = etl::type_list<T1, T2, T3>;
|
||||
#endif
|
||||
|
||||
//**********************************************
|
||||
message_router(etl::message_router_id_t id_)
|
||||
: imessage_router(id_)
|
||||
@ -2576,6 +2634,10 @@ namespace etl
|
||||
|
||||
typedef etl::message_packet<T1, T2> message_packet;
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
using type_list = etl::type_list<T1, T2>;
|
||||
#endif
|
||||
|
||||
//**********************************************
|
||||
message_router(etl::message_router_id_t id_)
|
||||
: imessage_router(id_)
|
||||
@ -2710,6 +2772,10 @@ namespace etl
|
||||
|
||||
typedef etl::message_packet< T1> message_packet;
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
using type_list = etl::type_list<T1>;
|
||||
#endif
|
||||
|
||||
//**********************************************
|
||||
message_router(etl::message_router_id_t id_)
|
||||
: imessage_router(id_)
|
||||
@ -2830,6 +2896,77 @@ namespace etl
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
// Helper: select type at index I from a `type_list`, or `void` if out of range.
|
||||
template <size_t I, typename TList>
|
||||
struct message_router_type_or_void
|
||||
{
|
||||
typedef typename etl::conditional<(I < etl::type_list_size<TList>::value),
|
||||
etl::type_list_type_at_index<TList, I>,
|
||||
etl::type_identity<void>>::type::type type;
|
||||
};
|
||||
|
||||
// For C++14 and below, map the `type_list` to up to 16 message type parameters (fill with `void`).
|
||||
template <typename TDerived, typename... TMessageTypes>
|
||||
class message_router<TDerived, etl::type_list<TMessageTypes...>, void, void, void, void, void, void, void, void, void, void, void, void, void, void, void>
|
||||
: public message_router<TDerived,
|
||||
typename etl::message_router_type_or_void<0, etl::type_list<TMessageTypes...>>::type,
|
||||
typename etl::message_router_type_or_void<1, etl::type_list<TMessageTypes...>>::type,
|
||||
typename etl::message_router_type_or_void<2, etl::type_list<TMessageTypes...>>::type,
|
||||
typename etl::message_router_type_or_void<3, etl::type_list<TMessageTypes...>>::type,
|
||||
typename etl::message_router_type_or_void<4, etl::type_list<TMessageTypes...>>::type,
|
||||
typename etl::message_router_type_or_void<5, etl::type_list<TMessageTypes...>>::type,
|
||||
typename etl::message_router_type_or_void<6, etl::type_list<TMessageTypes...>>::type,
|
||||
typename etl::message_router_type_or_void<7, etl::type_list<TMessageTypes...>>::type,
|
||||
typename etl::message_router_type_or_void<8, etl::type_list<TMessageTypes...>>::type,
|
||||
typename etl::message_router_type_or_void<9, etl::type_list<TMessageTypes...>>::type,
|
||||
typename etl::message_router_type_or_void<10, etl::type_list<TMessageTypes...>>::type,
|
||||
typename etl::message_router_type_or_void<11, etl::type_list<TMessageTypes...>>::type,
|
||||
typename etl::message_router_type_or_void<12, etl::type_list<TMessageTypes...>>::type,
|
||||
typename etl::message_router_type_or_void<13, etl::type_list<TMessageTypes...>>::type,
|
||||
typename etl::message_router_type_or_void<14, etl::type_list<TMessageTypes...>>::type,
|
||||
typename etl::message_router_type_or_void<15, etl::type_list<TMessageTypes...>>::type>
|
||||
{
|
||||
// Enforce the maximum number of message types supported by the C++14 implementation.
|
||||
static_assert(sizeof...(TMessageTypes) <= 16, "etl::message_router supports up to 16 message types for C++14");
|
||||
|
||||
public:
|
||||
using base = message_router<TDerived,
|
||||
typename etl::message_router_type_or_void<0, etl::type_list<TMessageTypes...>>::type,
|
||||
typename etl::message_router_type_or_void<1, etl::type_list<TMessageTypes...>>::type,
|
||||
typename etl::message_router_type_or_void<2, etl::type_list<TMessageTypes...>>::type,
|
||||
typename etl::message_router_type_or_void<3, etl::type_list<TMessageTypes...>>::type,
|
||||
typename etl::message_router_type_or_void<4, etl::type_list<TMessageTypes...>>::type,
|
||||
typename etl::message_router_type_or_void<5, etl::type_list<TMessageTypes...>>::type,
|
||||
typename etl::message_router_type_or_void<6, etl::type_list<TMessageTypes...>>::type,
|
||||
typename etl::message_router_type_or_void<7, etl::type_list<TMessageTypes...>>::type,
|
||||
typename etl::message_router_type_or_void<8, etl::type_list<TMessageTypes...>>::type,
|
||||
typename etl::message_router_type_or_void<9, etl::type_list<TMessageTypes...>>::type,
|
||||
typename etl::message_router_type_or_void<10, etl::type_list<TMessageTypes...>>::type,
|
||||
typename etl::message_router_type_or_void<11, etl::type_list<TMessageTypes...>>::type,
|
||||
typename etl::message_router_type_or_void<12, etl::type_list<TMessageTypes...>>::type,
|
||||
typename etl::message_router_type_or_void<13, etl::type_list<TMessageTypes...>>::type,
|
||||
typename etl::message_router_type_or_void<14, etl::type_list<TMessageTypes...>>::type,
|
||||
typename etl::message_router_type_or_void<15, etl::type_list<TMessageTypes...>>::type>;
|
||||
|
||||
using base::base; // Inherit constructors
|
||||
using typename base::message_packet;
|
||||
using type_list = etl::type_list<TMessageTypes...>;
|
||||
};
|
||||
#endif
|
||||
|
||||
#if ETL_USING_CPP11 && !defined(ETL_MESSAGE_ROUTER_FORCE_CPP03_IMPLEMENTATION)
|
||||
template <typename TDerived, typename... TMessageTypes>
|
||||
class message_router<TDerived, etl::type_list<TMessageTypes...>>
|
||||
: public message_router<TDerived, TMessageTypes...>
|
||||
{
|
||||
public:
|
||||
|
||||
using this_type = message_router<TDerived, etl::type_list<TMessageTypes...>>;
|
||||
using base_type = message_router<TDerived, TMessageTypes...>;
|
||||
using type_list = etl::type_list<TMessageTypes...>;
|
||||
using base_type::base_type;
|
||||
};
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -321,6 +321,8 @@ namespace etl
|
||||
{
|
||||
public:
|
||||
|
||||
using type_list = etl::type_list<T1>;
|
||||
|
||||
virtual ~observer() = default;
|
||||
|
||||
virtual void notification(T1) = 0;
|
||||
@ -337,6 +339,8 @@ namespace etl
|
||||
{
|
||||
public:
|
||||
|
||||
using type_list = etl::type_list<>;
|
||||
|
||||
virtual ~observer() = default;
|
||||
|
||||
virtual void notification() = 0;
|
||||
@ -358,6 +362,19 @@ namespace etl
|
||||
using type_list = etl::type_list<TTypes...>;
|
||||
};
|
||||
|
||||
//*****************************************************************
|
||||
/// The specialised observer class for etl::type_list.
|
||||
///\ingroup observer
|
||||
//****************************************************************
|
||||
template <typename... TTypes>
|
||||
class observer<etl::type_list<TTypes...>> : public observer<TTypes...>
|
||||
{
|
||||
public:
|
||||
|
||||
using observer<TTypes...>::observer;
|
||||
using observer<TTypes...>::notification;
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
//*********************************************************************
|
||||
|
||||
@ -33,6 +33,7 @@ SOFTWARE.
|
||||
|
||||
#include "platform.h"
|
||||
#include "type_traits.h"
|
||||
#include "type_list.h"
|
||||
|
||||
//*****************************************************************************
|
||||
///\defgroup visitor visitor
|
||||
@ -64,6 +65,7 @@ namespace etl
|
||||
|
||||
using visitable<T1>::accept;
|
||||
using visitable<Types...>::accept;
|
||||
using type_list = etl::type_list<T1, Types...>;
|
||||
};
|
||||
|
||||
//*****************************************************************
|
||||
@ -75,11 +77,30 @@ namespace etl
|
||||
{
|
||||
public:
|
||||
|
||||
using type_list = etl::type_list<T1>;
|
||||
|
||||
virtual ~visitable() = default;
|
||||
|
||||
virtual void accept(T1&) = 0;
|
||||
};
|
||||
|
||||
//*****************************************************************
|
||||
/// The visitable class for an etl::type_list.
|
||||
/// Expands the type_list into the existing variadic visitable.
|
||||
///\ingroup visitor
|
||||
//*****************************************************************
|
||||
template <typename... TTypes>
|
||||
class visitable<etl::type_list<TTypes...>> : public visitable<TTypes...>
|
||||
{
|
||||
ETL_STATIC_ASSERT(sizeof...(TTypes) != 0, "etl::type_list must not be empty");
|
||||
|
||||
public:
|
||||
|
||||
using type_list = etl::type_list<TTypes...>;
|
||||
|
||||
using visitable<TTypes...>::accept;
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
//*****************************************************************
|
||||
@ -187,6 +208,21 @@ namespace etl
|
||||
virtual void visit(T1) = 0;
|
||||
};
|
||||
|
||||
//*****************************************************************
|
||||
/// The visitor class for an etl::type_list.
|
||||
/// Expands the type_list into the existing variadic visitor.
|
||||
///\ingroup visitor
|
||||
//*****************************************************************
|
||||
template <typename... TTypes>
|
||||
class visitor<etl::type_list<TTypes...>> : public visitor<TTypes...>
|
||||
{
|
||||
ETL_STATIC_ASSERT(sizeof...(TTypes) != 0, "etl::type_list must not be empty");
|
||||
|
||||
public:
|
||||
|
||||
using visitor<TTypes...>::visit;
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
//*****************************************************************
|
||||
|
||||
741
test/test_message_router_with_type_list.cpp
Normal file
741
test/test_message_router_with_type_list.cpp
Normal file
@ -0,0 +1,741 @@
|
||||
/******************************************************************************
|
||||
The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
https://www.etlcpp.com
|
||||
|
||||
Copyright(c) 2017 John Wellbelove
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files(the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions :
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
#include "unit_test_framework.h"
|
||||
|
||||
#include "etl/message_router.h"
|
||||
#include "etl/queue.h"
|
||||
#include "etl/largest.h"
|
||||
|
||||
//***************************************************************************
|
||||
// The set of messages.
|
||||
//***************************************************************************
|
||||
namespace
|
||||
{
|
||||
enum
|
||||
{
|
||||
MESSAGE0,
|
||||
MESSAGE1,
|
||||
MESSAGE2,
|
||||
MESSAGE3,
|
||||
MESSAGE4,
|
||||
MESSAGE5
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
ROUTER1,
|
||||
ROUTER2,
|
||||
ROUTER3
|
||||
};
|
||||
|
||||
//***********************************
|
||||
struct NotInterface
|
||||
{
|
||||
virtual ~NotInterface() {}
|
||||
virtual int VirtualFunction() const = 0;
|
||||
};
|
||||
|
||||
////***********************************
|
||||
// Uncomment to demonstrate static assert
|
||||
//struct Message0 : public etl::message<MESSAGE0, NotInterface>
|
||||
//{
|
||||
//};
|
||||
|
||||
//***********************************
|
||||
struct Message1 : public etl::message<MESSAGE1>
|
||||
{
|
||||
Message1(etl::imessage_router& callback_)
|
||||
: callback(callback_)
|
||||
{
|
||||
}
|
||||
|
||||
etl::imessage_router& callback;
|
||||
};
|
||||
|
||||
//***********************************
|
||||
struct Message2 : public etl::message<MESSAGE2>
|
||||
{
|
||||
Message2(etl::imessage_router& callback_)
|
||||
: callback(callback_)
|
||||
{
|
||||
}
|
||||
|
||||
etl::imessage_router& callback;
|
||||
};
|
||||
|
||||
//***********************************
|
||||
struct Message3 : public etl::message<MESSAGE3>
|
||||
{
|
||||
Message3(etl::imessage_router& callback_)
|
||||
: callback(callback_)
|
||||
{
|
||||
}
|
||||
|
||||
etl::imessage_router& callback;
|
||||
int value[10];
|
||||
};
|
||||
|
||||
//***********************************
|
||||
struct Message4 : public etl::message<MESSAGE4>
|
||||
{
|
||||
Message4(etl::imessage_router& callback_)
|
||||
: callback(callback_)
|
||||
{
|
||||
}
|
||||
|
||||
etl::imessage_router& callback;
|
||||
};
|
||||
|
||||
//***********************************
|
||||
struct Message5 : public etl::message<MESSAGE5>
|
||||
{
|
||||
};
|
||||
|
||||
Message5 message5;
|
||||
|
||||
using Router1Messages = etl::type_list<Message1, Message2, Message3, Message4, Message5>;
|
||||
using Router2Messages = etl::type_list<Message1, Message2, Message4, Message5>;
|
||||
using Router3Messages = etl::type_list<Message1, Message2, Message3>;
|
||||
|
||||
//***************************************************************************
|
||||
// Router that handles messages 1, 2, 3, 4 and 5 and returns nothing.
|
||||
//***************************************************************************
|
||||
class Router1 : public etl::message_router<Router1, Router1Messages>
|
||||
{
|
||||
public:
|
||||
|
||||
Router1()
|
||||
: message_router(ROUTER1),
|
||||
message1_count(0),
|
||||
message2_count(0),
|
||||
message3_count(0),
|
||||
message4_count(0),
|
||||
message_unknown_count(0),
|
||||
callback_count(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void on_receive(const Message1& msg)
|
||||
{
|
||||
++message1_count;
|
||||
etl::send_message(msg.callback, message5);
|
||||
//CHECK_EQUAL(1, msg.VirtualFunction());
|
||||
}
|
||||
|
||||
void on_receive(const Message2& msg)
|
||||
{
|
||||
++message2_count;
|
||||
etl::send_message(msg.callback, message5);
|
||||
}
|
||||
|
||||
void on_receive(const Message3& msg)
|
||||
{
|
||||
++message3_count;
|
||||
etl::send_message(msg.callback, message5);
|
||||
}
|
||||
|
||||
void on_receive(const Message4& msg)
|
||||
{
|
||||
++message4_count;
|
||||
etl::send_message(msg.callback, message5);
|
||||
}
|
||||
|
||||
void on_receive(const Message5&)
|
||||
{
|
||||
++callback_count;
|
||||
}
|
||||
|
||||
void on_receive_unknown(const etl::imessage&)
|
||||
{
|
||||
++message_unknown_count;
|
||||
}
|
||||
|
||||
int message1_count;
|
||||
int message2_count;
|
||||
int message3_count;
|
||||
int message4_count;
|
||||
int message_unknown_count;
|
||||
int callback_count;
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
// Router that handles messages 1, 2, 4 and 5 and returns nothing.
|
||||
//***************************************************************************
|
||||
class Router2 : public etl::message_router<Router2, Router2Messages>
|
||||
{
|
||||
public:
|
||||
|
||||
Router2()
|
||||
: message_router(ROUTER2),
|
||||
message1_count(0),
|
||||
message2_count(0),
|
||||
message4_count(0),
|
||||
message_unknown_count(0),
|
||||
callback_count(0),
|
||||
sender_id(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Router2(etl::imessage_router& successor_)
|
||||
: message_router(ROUTER2, successor_),
|
||||
message1_count(0),
|
||||
message2_count(0),
|
||||
message4_count(0),
|
||||
message_unknown_count(0),
|
||||
callback_count(0),
|
||||
sender_id(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void on_receive(const Message1& msg)
|
||||
{
|
||||
++message1_count;
|
||||
sender_id = msg.callback.get_message_router_id();
|
||||
etl::send_message(msg.callback, message5);
|
||||
//CHECK_EQUAL(1, msg.VirtualFunction());
|
||||
}
|
||||
|
||||
void on_receive(const Message2& msg)
|
||||
{
|
||||
++message2_count;
|
||||
sender_id = msg.callback.get_message_router_id();
|
||||
etl::send_message(msg.callback, message5);
|
||||
}
|
||||
|
||||
void on_receive(const Message4& msg)
|
||||
{
|
||||
++message4_count;
|
||||
sender_id = msg.callback.get_message_router_id();
|
||||
etl::send_message(msg.callback, message5);
|
||||
}
|
||||
|
||||
void on_receive(const Message5&)
|
||||
{
|
||||
++callback_count;
|
||||
}
|
||||
|
||||
void on_receive_unknown(const etl::imessage&)
|
||||
{
|
||||
++message_unknown_count;
|
||||
sender_id = 0;
|
||||
}
|
||||
|
||||
int message1_count;
|
||||
int message2_count;
|
||||
int message4_count;
|
||||
int message_unknown_count;
|
||||
int callback_count;
|
||||
int sender_id;
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
// Router that handles messages 1, 2, 3.
|
||||
// 'receive' is overridden.
|
||||
//***************************************************************************
|
||||
class Router3 : public etl::message_router<Router3, Router3Messages>
|
||||
{
|
||||
public:
|
||||
|
||||
using base = etl::message_router<Router3, Router3Messages>;
|
||||
|
||||
Router3()
|
||||
: message_router(ROUTER3)
|
||||
, message1_received(false)
|
||||
, message2_received(false)
|
||||
, message3_received(false)
|
||||
, unknown_message_received(false)
|
||||
{
|
||||
}
|
||||
|
||||
void receive(const etl::imessage& msg) override
|
||||
{
|
||||
switch (msg.get_message_id())
|
||||
{
|
||||
case MESSAGE1:
|
||||
{
|
||||
message1_received = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case MESSAGE2:
|
||||
{
|
||||
message2_received = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case MESSAGE3:
|
||||
{
|
||||
message3_received = true;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
unknown_message_received = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void on_receive(const Message1&)
|
||||
{
|
||||
}
|
||||
|
||||
void on_receive(const Message2&)
|
||||
{
|
||||
}
|
||||
|
||||
void on_receive(const Message3&)
|
||||
{
|
||||
}
|
||||
|
||||
void on_receive_unknown(const etl::imessage&)
|
||||
{
|
||||
}
|
||||
|
||||
bool message1_received;
|
||||
bool message2_received;
|
||||
bool message3_received;
|
||||
bool unknown_message_received;
|
||||
};
|
||||
|
||||
etl::imessage_router* p_router;
|
||||
|
||||
SUITE(test_message_router_with_type_list)
|
||||
{
|
||||
//*************************************************************************
|
||||
TEST(message_router)
|
||||
{
|
||||
Router1 r1;
|
||||
Router2 r2;
|
||||
|
||||
p_router = &r1;
|
||||
|
||||
Message1 message1(r2);
|
||||
Message2 message2(r2);
|
||||
Message3 message3(r2);
|
||||
Message4 message4(r2);
|
||||
|
||||
// CHECK(!r1.is_null_router());
|
||||
CHECK(r1.is_producer());
|
||||
CHECK(r1.is_consumer());
|
||||
|
||||
p_router->receive(message1);
|
||||
CHECK_EQUAL(1, r1.message1_count);
|
||||
CHECK_EQUAL(0, r1.message2_count);
|
||||
CHECK_EQUAL(0, r1.message3_count);
|
||||
CHECK_EQUAL(0, r1.message4_count);
|
||||
CHECK_EQUAL(0, r1.message_unknown_count);
|
||||
CHECK_EQUAL(1, r2.callback_count);
|
||||
|
||||
p_router->receive(message2);
|
||||
CHECK_EQUAL(1, r1.message1_count);
|
||||
CHECK_EQUAL(1, r1.message2_count);
|
||||
CHECK_EQUAL(0, r1.message3_count);
|
||||
CHECK_EQUAL(0, r1.message4_count);
|
||||
CHECK_EQUAL(0, r1.message_unknown_count);
|
||||
CHECK_EQUAL(2, r2.callback_count);
|
||||
|
||||
p_router->receive(message3);
|
||||
CHECK_EQUAL(1, r1.message1_count);
|
||||
CHECK_EQUAL(1, r1.message2_count);
|
||||
CHECK_EQUAL(1, r1.message3_count);
|
||||
CHECK_EQUAL(0, r1.message4_count);
|
||||
CHECK_EQUAL(0, r1.message_unknown_count);
|
||||
CHECK_EQUAL(3, r2.callback_count);
|
||||
|
||||
p_router->receive(message4);
|
||||
CHECK_EQUAL(1, r1.message1_count);
|
||||
CHECK_EQUAL(1, r1.message2_count);
|
||||
CHECK_EQUAL(1, r1.message3_count);
|
||||
CHECK_EQUAL(1, r1.message4_count);
|
||||
CHECK_EQUAL(0, r1.message_unknown_count);
|
||||
CHECK_EQUAL(4, r2.callback_count);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(message_null_router)
|
||||
{
|
||||
Router2 router;
|
||||
etl::null_message_router null_router;
|
||||
|
||||
Message1 message1(null_router);
|
||||
Message2 message2(null_router);
|
||||
Message3 message3(null_router);
|
||||
Message4 message4(null_router);
|
||||
|
||||
// CHECK(null_router.is_null_router());
|
||||
CHECK(!null_router.is_producer());
|
||||
CHECK(!null_router.is_consumer());
|
||||
|
||||
// Send from the null router.
|
||||
etl::send_message(router, message1);
|
||||
CHECK_EQUAL(1, router.message1_count);
|
||||
CHECK_EQUAL(0, router.message2_count);
|
||||
CHECK_EQUAL(0, router.message4_count);
|
||||
CHECK_EQUAL(0, router.message_unknown_count);
|
||||
|
||||
etl::send_message(router, message2);
|
||||
CHECK_EQUAL(1, router.message1_count);
|
||||
CHECK_EQUAL(1, router.message2_count);
|
||||
CHECK_EQUAL(0, router.message4_count);
|
||||
CHECK_EQUAL(0, router.message_unknown_count);
|
||||
|
||||
etl::send_message(router, message3);
|
||||
CHECK_EQUAL(1, router.message1_count);
|
||||
CHECK_EQUAL(1, router.message2_count);
|
||||
CHECK_EQUAL(0, router.message4_count);
|
||||
CHECK_EQUAL(1, router.message_unknown_count);
|
||||
|
||||
etl::send_message(router, message4);
|
||||
CHECK_EQUAL(1, router.message1_count);
|
||||
CHECK_EQUAL(1, router.message2_count);
|
||||
CHECK_EQUAL(1, router.message4_count);
|
||||
CHECK_EQUAL(1, router.message_unknown_count);
|
||||
|
||||
// Send to the null router.
|
||||
etl::send_message(null_router, message1);
|
||||
CHECK_EQUAL(1, router.message1_count);
|
||||
CHECK_EQUAL(1, router.message2_count);
|
||||
CHECK_EQUAL(1, router.message4_count);
|
||||
CHECK_EQUAL(1, router.message_unknown_count);
|
||||
|
||||
etl::send_message(null_router, message2);
|
||||
CHECK_EQUAL(1, router.message1_count);
|
||||
CHECK_EQUAL(1, router.message2_count);
|
||||
CHECK_EQUAL(1, router.message4_count);
|
||||
CHECK_EQUAL(1, router.message_unknown_count);
|
||||
|
||||
etl::send_message(null_router, message3);
|
||||
CHECK_EQUAL(1, router.message1_count);
|
||||
CHECK_EQUAL(1, router.message2_count);
|
||||
CHECK_EQUAL(1, router.message4_count);
|
||||
CHECK_EQUAL(1, router.message_unknown_count);
|
||||
|
||||
etl::send_message(null_router, message4);
|
||||
CHECK_EQUAL(1, router.message1_count);
|
||||
CHECK_EQUAL(1, router.message2_count);
|
||||
CHECK_EQUAL(1, router.message4_count);
|
||||
CHECK_EQUAL(1, router.message_unknown_count);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(message_producer)
|
||||
{
|
||||
Router2 router;
|
||||
etl::message_producer producer(ROUTER3);
|
||||
|
||||
Message1 message1(producer);
|
||||
Message2 message2(producer);
|
||||
Message3 message3(producer);
|
||||
Message4 message4(producer);
|
||||
|
||||
// CHECK(!producer.is_null_router());
|
||||
CHECK(producer.is_producer());
|
||||
CHECK(!producer.is_consumer());
|
||||
|
||||
CHECK_EQUAL(0, router.sender_id);
|
||||
|
||||
// Send from the producer.
|
||||
router.receive(message1);
|
||||
//etl::send_message(router, message1);
|
||||
CHECK_EQUAL(1, router.message1_count);
|
||||
CHECK_EQUAL(0, router.message2_count);
|
||||
CHECK_EQUAL(0, router.message4_count);
|
||||
CHECK_EQUAL(0, router.message_unknown_count);
|
||||
CHECK_EQUAL(ROUTER3, router.sender_id);
|
||||
|
||||
etl::send_message(router, message2);
|
||||
CHECK_EQUAL(1, router.message1_count);
|
||||
CHECK_EQUAL(1, router.message2_count);
|
||||
CHECK_EQUAL(0, router.message4_count);
|
||||
CHECK_EQUAL(0, router.message_unknown_count);
|
||||
CHECK_EQUAL(ROUTER3, router.sender_id);
|
||||
|
||||
etl::send_message(router, message3);
|
||||
CHECK_EQUAL(1, router.message1_count);
|
||||
CHECK_EQUAL(1, router.message2_count);
|
||||
CHECK_EQUAL(0, router.message4_count);
|
||||
CHECK_EQUAL(1, router.message_unknown_count);
|
||||
CHECK_EQUAL(0, router.sender_id);
|
||||
|
||||
etl::send_message(router, message4);
|
||||
CHECK_EQUAL(1, router.message1_count);
|
||||
CHECK_EQUAL(1, router.message2_count);
|
||||
CHECK_EQUAL(1, router.message4_count);
|
||||
CHECK_EQUAL(1, router.message_unknown_count);
|
||||
CHECK_EQUAL(ROUTER3, router.sender_id);
|
||||
|
||||
// Send to the producer.
|
||||
etl::send_message(producer, message1);
|
||||
CHECK_EQUAL(1, router.message1_count);
|
||||
CHECK_EQUAL(1, router.message2_count);
|
||||
CHECK_EQUAL(1, router.message4_count);
|
||||
CHECK_EQUAL(1, router.message_unknown_count);
|
||||
|
||||
etl::send_message(producer, message2);
|
||||
CHECK_EQUAL(1, router.message1_count);
|
||||
CHECK_EQUAL(1, router.message2_count);
|
||||
CHECK_EQUAL(1, router.message4_count);
|
||||
CHECK_EQUAL(1, router.message_unknown_count);
|
||||
|
||||
etl::send_message(producer, message3);
|
||||
CHECK_EQUAL(1, router.message1_count);
|
||||
CHECK_EQUAL(1, router.message2_count);
|
||||
CHECK_EQUAL(1, router.message4_count);
|
||||
CHECK_EQUAL(1, router.message_unknown_count);
|
||||
|
||||
etl::send_message(producer, message4);
|
||||
CHECK_EQUAL(1, router.message1_count);
|
||||
CHECK_EQUAL(1, router.message2_count);
|
||||
CHECK_EQUAL(1, router.message4_count);
|
||||
CHECK_EQUAL(1, router.message_unknown_count);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(message_router_accepts)
|
||||
{
|
||||
Router2 r2;
|
||||
|
||||
etl::null_message_router null_router;
|
||||
|
||||
Message1 message1(null_router);
|
||||
Message2 message2(null_router);
|
||||
Message3 message3(null_router);
|
||||
Message4 message4(null_router);
|
||||
|
||||
CHECK(r2.accepts(message1));
|
||||
CHECK(r2.accepts(message1.get_message_id()));
|
||||
|
||||
CHECK(r2.accepts(message2));
|
||||
CHECK(r2.accepts(message2.get_message_id()));
|
||||
|
||||
CHECK(!r2.accepts(message3));
|
||||
CHECK(!r2.accepts(message3.get_message_id()));
|
||||
|
||||
CHECK(r2.accepts(message4));
|
||||
CHECK(r2.accepts(message4.get_message_id()));
|
||||
|
||||
CHECK(r2.accepts(message5));
|
||||
CHECK(r2.accepts(message5.get_message_id()));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(message_router_accepts_successors)
|
||||
{
|
||||
Router1 r1; // M1, M2, M3, M4, M5
|
||||
Router2 r2; // M1, M2, M4, M5
|
||||
|
||||
r2.set_successor(r1);
|
||||
|
||||
etl::null_message_router null_router;
|
||||
|
||||
Message1 message1(null_router);
|
||||
Message2 message2(null_router);
|
||||
Message3 message3(null_router);
|
||||
Message4 message4(null_router);
|
||||
|
||||
CHECK(r2.accepts(message1));
|
||||
CHECK(r2.accepts(message1.get_message_id()));
|
||||
|
||||
CHECK(r2.accepts(message2));
|
||||
CHECK(r2.accepts(message2.get_message_id()));
|
||||
|
||||
CHECK(r2.accepts(message3));
|
||||
CHECK(r2.accepts(message3.get_message_id()));
|
||||
|
||||
CHECK(r2.accepts(message4));
|
||||
CHECK(r2.accepts(message4.get_message_id()));
|
||||
|
||||
CHECK(r2.accepts(message5));
|
||||
CHECK(r2.accepts(message5.get_message_id()));
|
||||
}
|
||||
|
||||
#if ETL_HAS_VIRTUAL_MESSAGES
|
||||
//*************************************************************************
|
||||
TEST(message_router_queue)
|
||||
{
|
||||
Router1 r1;
|
||||
Router2 r2;
|
||||
|
||||
typedef Router2::message_packet Packet;
|
||||
typedef etl::queue<Packet, 4> Queue;
|
||||
|
||||
Queue queue;
|
||||
|
||||
etl::imessage* im;
|
||||
|
||||
Message1 message1(r1);
|
||||
Message2 message2(r1);
|
||||
Message3 message3(r1);
|
||||
Message4 message4(r1);
|
||||
|
||||
// Queue some messages in the message packet queue.
|
||||
im = &message1;
|
||||
queue.emplace(*im);
|
||||
|
||||
im = &message2;
|
||||
queue.emplace(*im);
|
||||
|
||||
// The router2 queue doesn't accept Message3 types.
|
||||
im = &message3;
|
||||
CHECK_THROW(queue.emplace(*im), etl::unhandled_message_exception);
|
||||
|
||||
im = &message4;
|
||||
queue.emplace(*im);
|
||||
|
||||
im = &message4;
|
||||
queue.emplace(*im);
|
||||
|
||||
etl::imessage& imr1 = queue.front().get();
|
||||
r2.receive(imr1);
|
||||
CHECK_EQUAL(1, r2.message1_count);
|
||||
CHECK_EQUAL(0, r2.message2_count);
|
||||
CHECK_EQUAL(0, r2.message4_count);
|
||||
CHECK_EQUAL(0, r2.message_unknown_count);
|
||||
CHECK_EQUAL(1, r1.callback_count);
|
||||
queue.pop();
|
||||
|
||||
etl::imessage& imr2 = queue.front().get();
|
||||
r2.receive(imr2);
|
||||
CHECK_EQUAL(1, r2.message1_count);
|
||||
CHECK_EQUAL(1, r2.message2_count);
|
||||
CHECK_EQUAL(0, r2.message4_count);
|
||||
CHECK_EQUAL(0, r2.message_unknown_count);
|
||||
CHECK_EQUAL(2, r1.callback_count);
|
||||
queue.pop();
|
||||
|
||||
const etl::imessage& imr3 = queue.front().get();
|
||||
r2.receive(imr3);
|
||||
CHECK_EQUAL(1, r2.message1_count);
|
||||
CHECK_EQUAL(1, r2.message2_count);
|
||||
CHECK_EQUAL(1, r2.message4_count);
|
||||
CHECK_EQUAL(0, r2.message_unknown_count);
|
||||
CHECK_EQUAL(3, r1.callback_count);
|
||||
queue.pop();
|
||||
|
||||
const Queue& crqueue = queue;
|
||||
const etl::imessage& imr4 = crqueue.front().get();
|
||||
r2.receive(imr4);
|
||||
CHECK_EQUAL(1, r2.message1_count);
|
||||
CHECK_EQUAL(1, r2.message2_count);
|
||||
CHECK_EQUAL(2, r2.message4_count);
|
||||
CHECK_EQUAL(0, r2.message_unknown_count);
|
||||
CHECK_EQUAL(4, r1.callback_count);
|
||||
queue.pop();
|
||||
}
|
||||
#endif
|
||||
|
||||
//*************************************************************************
|
||||
TEST(message_router_successor)
|
||||
{
|
||||
Router1 r1;
|
||||
Router2 r2(r1);
|
||||
|
||||
etl::null_message_router null_router;
|
||||
|
||||
Message1 message1(r2);
|
||||
Message2 message2(r2);
|
||||
Message3 message3(r2);
|
||||
Message4 message4(r2);
|
||||
|
||||
etl::send_message(r2, message1);
|
||||
CHECK_EQUAL(1, r2.message1_count);
|
||||
CHECK_EQUAL(0, r2.message2_count);
|
||||
CHECK_EQUAL(0, r2.message4_count);
|
||||
CHECK_EQUAL(0, r2.message_unknown_count);
|
||||
|
||||
CHECK_EQUAL(0, r1.message1_count);
|
||||
CHECK_EQUAL(0, r1.message2_count);
|
||||
CHECK_EQUAL(0, r1.message3_count);
|
||||
CHECK_EQUAL(0, r1.message4_count);
|
||||
CHECK_EQUAL(0, r1.message_unknown_count);
|
||||
|
||||
etl::send_message(r2, message2);
|
||||
CHECK_EQUAL(1, r2.message1_count);
|
||||
CHECK_EQUAL(1, r2.message2_count);
|
||||
CHECK_EQUAL(0, r2.message4_count);
|
||||
CHECK_EQUAL(0, r2.message_unknown_count);
|
||||
|
||||
CHECK_EQUAL(0, r1.message1_count);
|
||||
CHECK_EQUAL(0, r1.message2_count);
|
||||
CHECK_EQUAL(0, r1.message3_count);
|
||||
CHECK_EQUAL(0, r1.message4_count);
|
||||
CHECK_EQUAL(0, r1.message_unknown_count);
|
||||
|
||||
r2.receive(message3);
|
||||
CHECK_EQUAL(1, r2.message1_count);
|
||||
CHECK_EQUAL(1, r2.message2_count);
|
||||
CHECK_EQUAL(0, r2.message4_count);
|
||||
CHECK_EQUAL(0, r2.message_unknown_count);
|
||||
|
||||
CHECK_EQUAL(0, r1.message1_count);
|
||||
CHECK_EQUAL(0, r1.message2_count);
|
||||
CHECK_EQUAL(1, r1.message3_count);
|
||||
CHECK_EQUAL(0, r1.message4_count);
|
||||
CHECK_EQUAL(0, r1.message_unknown_count);
|
||||
|
||||
etl::send_message(r2, message4);
|
||||
CHECK_EQUAL(1, r2.message1_count);
|
||||
CHECK_EQUAL(1, r2.message2_count);
|
||||
CHECK_EQUAL(1, r2.message4_count);
|
||||
CHECK_EQUAL(0, r2.message_unknown_count);
|
||||
|
||||
CHECK_EQUAL(0, r1.message1_count);
|
||||
CHECK_EQUAL(0, r1.message2_count);
|
||||
CHECK_EQUAL(1, r1.message3_count);
|
||||
CHECK_EQUAL(0, r1.message4_count);
|
||||
CHECK_EQUAL(0, r1.message_unknown_count);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(message_router_with_overloaded_receive)
|
||||
{
|
||||
Router3 router;
|
||||
|
||||
Message1 message1(router);
|
||||
Message2 message2(router);
|
||||
Message3 message3(router);
|
||||
|
||||
router.receive(message1);
|
||||
CHECK_TRUE(router.message1_received);
|
||||
|
||||
router.receive(message2);
|
||||
CHECK_TRUE(router.message2_received);
|
||||
|
||||
router.receive(message3);
|
||||
CHECK_TRUE(router.message3_received);
|
||||
|
||||
CHECK_FALSE(router.unknown_message_received);
|
||||
}
|
||||
}
|
||||
}
|
||||
583
test/test_observer_with_type_list.cpp
Normal file
583
test/test_observer_with_type_list.cpp
Normal file
@ -0,0 +1,583 @@
|
||||
/******************************************************************************
|
||||
The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
https://www.etlcpp.com
|
||||
|
||||
Copyright(c) 2025 John Wellbelove
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files(the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions :
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
#include "unit_test_framework.h"
|
||||
|
||||
#include "etl/observer.h"
|
||||
#include "etl/type_list.h"
|
||||
|
||||
#if ETL_USING_CPP11 && !defined(ETL_VISITOR_FORCE_CPP03_IMPLEMENTATION)
|
||||
|
||||
namespace
|
||||
{
|
||||
//*****************************************************************************
|
||||
// Notification1
|
||||
//*****************************************************************************
|
||||
struct Notification1
|
||||
{
|
||||
};
|
||||
|
||||
//*****************************************************************************
|
||||
// Notification2
|
||||
//*****************************************************************************
|
||||
struct Notification2
|
||||
{
|
||||
};
|
||||
|
||||
//*****************************************************************************
|
||||
// Notification3
|
||||
//*****************************************************************************
|
||||
struct Notification3
|
||||
{
|
||||
};
|
||||
|
||||
//*****************************************************************************
|
||||
// Generic notification.
|
||||
//*****************************************************************************
|
||||
template <const int ID>
|
||||
struct Notification
|
||||
{
|
||||
};
|
||||
|
||||
//*****************************************************************************
|
||||
// The observer base type.
|
||||
// Declare what notifications you want to observe and how they are passed to 'notification'.
|
||||
// The Notification1 is passed by value.
|
||||
// The Notification2 is passed by reference.
|
||||
// The Notification3 is passed by const reference.
|
||||
//*****************************************************************************
|
||||
using NotificationTypes = etl::type_list<Notification1, Notification2&, const Notification3&>;
|
||||
using ObserverType = etl::observer<NotificationTypes>;
|
||||
|
||||
//*****************************************************************************
|
||||
// The observer base type that does not take a notification type.
|
||||
//*****************************************************************************
|
||||
typedef etl::observer<void, int> ObserverVoidIntType;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
// The concrete observable 1 class.
|
||||
//*****************************************************************************
|
||||
class Observable1 : public etl::observable<ObserverType, 2>
|
||||
{
|
||||
public:
|
||||
|
||||
Notification1 data1;
|
||||
Notification2 data2;
|
||||
Notification1& data3 = data1;
|
||||
|
||||
//*********************************
|
||||
// Notify all of the observers.
|
||||
//*********************************
|
||||
void send_notifications()
|
||||
{
|
||||
notify_observers(data3);
|
||||
notify_observers(data2);
|
||||
}
|
||||
};
|
||||
|
||||
//*****************************************************************************
|
||||
// The concrete observable 2 class.
|
||||
//*****************************************************************************
|
||||
class Observable2 : public etl::observable<ObserverType, 2>
|
||||
{
|
||||
public:
|
||||
|
||||
Notification3 data3;
|
||||
|
||||
//*********************************
|
||||
// Notify all of the observers.
|
||||
//*********************************
|
||||
void send_notifications()
|
||||
{
|
||||
notify_observers(data3);
|
||||
}
|
||||
};
|
||||
|
||||
//*****************************************************************************
|
||||
// The concrete observable 3 class.
|
||||
//*****************************************************************************
|
||||
class ObservableVoidInt : public etl::observable<ObserverVoidIntType, 2>
|
||||
{
|
||||
public:
|
||||
|
||||
//*********************************
|
||||
// Notify all of the observers.
|
||||
//*********************************
|
||||
void send_notifications()
|
||||
{
|
||||
notify_observers();
|
||||
}
|
||||
|
||||
//*********************************
|
||||
// Notify all of the observers.
|
||||
//*********************************
|
||||
void send_notifications(int n)
|
||||
{
|
||||
notify_observers(n);
|
||||
}
|
||||
};
|
||||
|
||||
//*****************************************************************************
|
||||
// The first observer type.
|
||||
// If any one of the overloads is missing or a parameter declaration is incorrect
|
||||
// then the class will be 'abstract' and will not compile.
|
||||
//*****************************************************************************
|
||||
class Observer1 : public ObserverType
|
||||
{
|
||||
public:
|
||||
|
||||
Observer1()
|
||||
: data1_count(0)
|
||||
, data2_count(0)
|
||||
, data3_count(0)
|
||||
{
|
||||
}
|
||||
|
||||
//*******************************************
|
||||
// Notification1 is passed by value.
|
||||
//*******************************************
|
||||
void notification(Notification1 /*data1*/)
|
||||
{
|
||||
++data1_count;
|
||||
}
|
||||
|
||||
//*******************************************
|
||||
// Notification2 is passed by reference.
|
||||
//*******************************************
|
||||
void notification(Notification2& /*data2*/)
|
||||
{
|
||||
++data2_count;
|
||||
}
|
||||
|
||||
//*******************************************
|
||||
// Notification3 is passed by const reference.
|
||||
//*******************************************
|
||||
void notification(const Notification3& /*data3*/)
|
||||
{
|
||||
++data3_count;
|
||||
}
|
||||
|
||||
int data1_count;
|
||||
int data2_count;
|
||||
int data3_count;
|
||||
};
|
||||
|
||||
//*****************************************************************************
|
||||
// The second observer type.
|
||||
// If any one of the overloads is missing or a parameter declaration is incorrect
|
||||
// then the class will be 'abstract' and will not compile.
|
||||
//*****************************************************************************
|
||||
class Observer2 : public ObserverType
|
||||
{
|
||||
public:
|
||||
|
||||
Observer2()
|
||||
: data1_count(0)
|
||||
, data2_count(0)
|
||||
, data3_count(0)
|
||||
{
|
||||
}
|
||||
|
||||
//*******************************************
|
||||
// Notification1 is passed by value.
|
||||
//*******************************************
|
||||
void notification(Notification1 /*data1*/)
|
||||
{
|
||||
++data1_count;
|
||||
}
|
||||
|
||||
//*******************************************
|
||||
// Notification2 is passed by reference.
|
||||
//*******************************************
|
||||
void notification(Notification2& /*data2*/)
|
||||
{
|
||||
++data2_count;
|
||||
}
|
||||
|
||||
//*******************************************
|
||||
// Notification3 is passed by const reference.
|
||||
//*******************************************
|
||||
void notification(const Notification3& /*data3*/)
|
||||
{
|
||||
++data3_count;
|
||||
}
|
||||
|
||||
int data1_count;
|
||||
int data2_count;
|
||||
int data3_count;
|
||||
};
|
||||
|
||||
//*****************************************************************************
|
||||
// The third observer type.
|
||||
// If any one of the overloads is missing or a parameter declaration is incorrect
|
||||
// then the class will be 'abstract' and will not compile.
|
||||
//*****************************************************************************
|
||||
class ObserverVoidInt : public ObserverVoidIntType
|
||||
{
|
||||
public:
|
||||
|
||||
ObserverVoidInt()
|
||||
: data1_count(0)
|
||||
, data2_count(0)
|
||||
{
|
||||
}
|
||||
|
||||
//*******************************************
|
||||
// Notification1
|
||||
//*******************************************
|
||||
void notification() override
|
||||
{
|
||||
++data1_count;
|
||||
}
|
||||
|
||||
//*******************************************
|
||||
// Notification2
|
||||
//*******************************************
|
||||
void notification(int) override
|
||||
{
|
||||
++data2_count;
|
||||
}
|
||||
|
||||
int data1_count;
|
||||
int data2_count;
|
||||
};
|
||||
|
||||
namespace
|
||||
{
|
||||
SUITE(test_observer)
|
||||
{
|
||||
//*************************************************************************
|
||||
TEST(test_2_observables_2_observers_3_notifications)
|
||||
{
|
||||
// The observable objects.
|
||||
Observable1 observable1;
|
||||
Observable2 observable2;
|
||||
|
||||
// The observer objects.
|
||||
Observer1 observer1;
|
||||
Observer2 observer2;
|
||||
|
||||
observable1.add_observer(observer1);
|
||||
|
||||
// Send the notifications.
|
||||
observable1.send_notifications(); // Updates data1 & data2.
|
||||
|
||||
CHECK_EQUAL(1, observer1.data1_count);
|
||||
CHECK_EQUAL(1, observer1.data2_count);
|
||||
CHECK_EQUAL(0, observer1.data3_count);
|
||||
|
||||
CHECK_EQUAL(0, observer2.data1_count);
|
||||
CHECK_EQUAL(0, observer2.data2_count);
|
||||
CHECK_EQUAL(0, observer2.data3_count);
|
||||
|
||||
observable2.send_notifications(); // Updates data3. observeable2 has no observers yet.
|
||||
|
||||
CHECK_EQUAL(1, observer1.data1_count);
|
||||
CHECK_EQUAL(1, observer1.data2_count);
|
||||
CHECK_EQUAL(0, observer1.data3_count);
|
||||
|
||||
CHECK_EQUAL(0, observer2.data1_count);
|
||||
CHECK_EQUAL(0, observer2.data2_count);
|
||||
CHECK_EQUAL(0, observer2.data3_count);
|
||||
|
||||
// Add an observer to both.
|
||||
observable1.add_observer(observer2);
|
||||
observable2.add_observer(observer2);
|
||||
|
||||
// Send the notifications.
|
||||
observable1.send_notifications(); // Updates data1 & data2.
|
||||
|
||||
CHECK_EQUAL(2, observer1.data1_count);
|
||||
CHECK_EQUAL(2, observer1.data2_count);
|
||||
CHECK_EQUAL(0, observer1.data3_count);
|
||||
|
||||
CHECK_EQUAL(1, observer2.data1_count);
|
||||
CHECK_EQUAL(1, observer2.data2_count);
|
||||
CHECK_EQUAL(0, observer2.data3_count);
|
||||
|
||||
observable2.send_notifications(); // Updates data3.
|
||||
|
||||
CHECK_EQUAL(2, observer1.data1_count);
|
||||
CHECK_EQUAL(2, observer1.data2_count);
|
||||
CHECK_EQUAL(0, observer1.data3_count);
|
||||
|
||||
CHECK_EQUAL(1, observer2.data1_count);
|
||||
CHECK_EQUAL(1, observer2.data2_count);
|
||||
CHECK_EQUAL(1, observer2.data3_count);
|
||||
|
||||
observable1.remove_observer(observer1);
|
||||
|
||||
// Send the notifications.
|
||||
observable1.send_notifications(); // Updates data1 & data2.
|
||||
|
||||
CHECK_EQUAL(2, observer1.data1_count);
|
||||
CHECK_EQUAL(2, observer1.data2_count);
|
||||
CHECK_EQUAL(0, observer1.data3_count);
|
||||
|
||||
CHECK_EQUAL(2, observer2.data1_count);
|
||||
CHECK_EQUAL(2, observer2.data2_count);
|
||||
CHECK_EQUAL(1, observer2.data3_count);
|
||||
|
||||
observable2.send_notifications(); // Updates data3.
|
||||
|
||||
CHECK_EQUAL(2, observer1.data1_count);
|
||||
CHECK_EQUAL(2, observer1.data2_count);
|
||||
CHECK_EQUAL(0, observer1.data3_count);
|
||||
|
||||
CHECK_EQUAL(2, observer2.data1_count);
|
||||
CHECK_EQUAL(2, observer2.data2_count);
|
||||
CHECK_EQUAL(2, observer2.data3_count);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_observable_2_observers_enable_disable)
|
||||
{
|
||||
// The observable objects.
|
||||
Observable1 observable1;
|
||||
|
||||
// The observer objects.
|
||||
Observer1 observer1;
|
||||
Observer2 observer2;
|
||||
|
||||
observable1.add_observer(observer1);
|
||||
observable1.add_observer(observer2);
|
||||
|
||||
// Send the notifications.
|
||||
observable1.send_notifications();
|
||||
|
||||
CHECK_EQUAL(1, observer1.data1_count);
|
||||
CHECK_EQUAL(1, observer2.data1_count);
|
||||
|
||||
// Disable observer1. Send the notifications.
|
||||
observable1.disable_observer(observer1);
|
||||
observable1.send_notifications();
|
||||
|
||||
CHECK_EQUAL(1, observer1.data1_count);
|
||||
CHECK_EQUAL(2, observer2.data1_count);
|
||||
|
||||
// Disable observer2. Send the notifications.
|
||||
observable1.enable_observer(observer2, false);
|
||||
observable1.send_notifications();
|
||||
|
||||
CHECK_EQUAL(1, observer1.data1_count);
|
||||
CHECK_EQUAL(2, observer2.data1_count);
|
||||
|
||||
// Enable observer1. Send the notifications.
|
||||
observable1.enable_observer(observer1);
|
||||
observable1.send_notifications();
|
||||
|
||||
CHECK_EQUAL(2, observer1.data1_count);
|
||||
CHECK_EQUAL(2, observer2.data1_count);
|
||||
|
||||
// Enable observer2. Send the notifications.
|
||||
observable1.enable_observer(observer2, true);
|
||||
observable1.send_notifications();
|
||||
|
||||
CHECK_EQUAL(3, observer1.data1_count);
|
||||
CHECK_EQUAL(3, observer2.data1_count);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_8_notifications)
|
||||
{
|
||||
typedef etl::observer<Notification<1>, Notification<2>, Notification<3>, Notification<4>, Notification<5>, Notification<6>, Notification<7>, Notification<8> > Observer;
|
||||
|
||||
class Observable : public etl::observable<Observer, 1>
|
||||
{
|
||||
};
|
||||
|
||||
// This test just needs to compile without errors.
|
||||
CHECK(true);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_7_notifications)
|
||||
{
|
||||
typedef etl::observer<Notification<1>, Notification<2>, Notification<3>, Notification<4>, Notification<5>, Notification<6>, Notification<7> > Observer;
|
||||
|
||||
class Observable : public etl::observable<Observer, 1>
|
||||
{
|
||||
};
|
||||
|
||||
// This test just needs to compile without errors.
|
||||
CHECK(true);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_6_notifications)
|
||||
{
|
||||
typedef etl::observer<Notification<1>, Notification<2>, Notification<3>, Notification<4>, Notification<5>, Notification<6> > Observer;
|
||||
|
||||
class Observable : public etl::observable<Observer, 1>
|
||||
{
|
||||
};
|
||||
|
||||
// This test just needs to compile without errors.
|
||||
CHECK(true);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_5_notifications)
|
||||
{
|
||||
typedef etl::observer<Notification<1>, Notification<2>, Notification<3>, Notification<4>, Notification<5> > Observer;
|
||||
|
||||
class Observable : public etl::observable<Observer, 1>
|
||||
{
|
||||
};
|
||||
|
||||
// This test just needs to compile without errors.
|
||||
CHECK(true);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_4_notifications)
|
||||
{
|
||||
typedef etl::observer<Notification<1>, Notification<2>, Notification<3>, Notification<4> > Observer;
|
||||
|
||||
class Observable : public etl::observable<Observer, 1>
|
||||
{
|
||||
};
|
||||
|
||||
// This test just needs to compile without errors.
|
||||
CHECK(true);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_3_notifications)
|
||||
{
|
||||
typedef etl::observer<Notification<1>, Notification<2>, Notification<3> > Observer;
|
||||
|
||||
class Observable : public etl::observable<Observer, 1>
|
||||
{
|
||||
};
|
||||
|
||||
// This test just needs to compile without errors.
|
||||
CHECK(true);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_2_notifications)
|
||||
{
|
||||
typedef etl::observer<Notification<1>, Notification<2> > Observer;
|
||||
|
||||
class Observable : public etl::observable<Observer, 1>
|
||||
{
|
||||
};
|
||||
|
||||
// This test just needs to compile without errors.
|
||||
CHECK(true);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_1_notification)
|
||||
{
|
||||
typedef etl::observer<Notification<1> > Observer;
|
||||
|
||||
class Observable : public etl::observable<Observer, 1>
|
||||
{
|
||||
};
|
||||
|
||||
// This test just needs to compile without errors.
|
||||
CHECK(true);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_observer_list)
|
||||
{
|
||||
class Observer : public etl::observer<Notification1>
|
||||
{
|
||||
void notification(Notification1) {}
|
||||
};
|
||||
|
||||
class Observable : public etl::observable<Observer, 4>
|
||||
{
|
||||
};
|
||||
|
||||
Observable observable;
|
||||
|
||||
Observer observer1;
|
||||
Observer observer2;
|
||||
Observer observer3;
|
||||
Observer observer4;
|
||||
Observer observer5;
|
||||
|
||||
observable.add_observer(observer1);
|
||||
CHECK_EQUAL(1UL, observable.number_of_observers());
|
||||
|
||||
observable.add_observer(observer2);
|
||||
CHECK_EQUAL(2UL, observable.number_of_observers());
|
||||
|
||||
observable.add_observer(observer3);
|
||||
CHECK_EQUAL(3UL, observable.number_of_observers());
|
||||
|
||||
observable.add_observer(observer2);
|
||||
CHECK_EQUAL(3UL, observable.number_of_observers());
|
||||
|
||||
observable.add_observer(observer4);
|
||||
CHECK_EQUAL(4UL, observable.number_of_observers());
|
||||
|
||||
CHECK_THROW(observable.add_observer(observer5), etl::observer_list_full);
|
||||
|
||||
CHECK(observable.remove_observer(observer3));
|
||||
CHECK_EQUAL(3UL, observable.number_of_observers());
|
||||
|
||||
// Try again.
|
||||
CHECK(!observable.remove_observer(observer3));
|
||||
CHECK_EQUAL(3UL, observable.number_of_observers());
|
||||
|
||||
observable.clear_observers();
|
||||
CHECK_EQUAL(0UL, observable.number_of_observers());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_void_int_observable)
|
||||
{
|
||||
// The observable objects.
|
||||
ObservableVoidInt observable;
|
||||
|
||||
// The observer objects.
|
||||
ObserverVoidInt observer;
|
||||
|
||||
observable.add_observer(observer);
|
||||
|
||||
// Send the notifications.
|
||||
observable.send_notifications();
|
||||
CHECK_EQUAL(1U, observer.data1_count);
|
||||
CHECK_EQUAL(0U, observer.data2_count);
|
||||
|
||||
observable.send_notifications(1);
|
||||
CHECK_EQUAL(1U, observer.data1_count);
|
||||
CHECK_EQUAL(1U, observer.data2_count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
761
test/test_visitor_with_type_list.cpp
Normal file
761
test/test_visitor_with_type_list.cpp
Normal file
@ -0,0 +1,761 @@
|
||||
/******************************************************************************
|
||||
The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
https://www.etlcpp.com
|
||||
|
||||
Copyright(c) 2025 John Wellbelove
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files(the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions :
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
#include "unit_test_framework.h"
|
||||
|
||||
#include "etl/visitor.h"
|
||||
|
||||
#if ETL_USING_CPP11 && !defined(ETL_VISITOR_FORCE_CPP03_IMPLEMENTATION)
|
||||
|
||||
//*****************************************************************************
|
||||
// Pre-declare the data types.
|
||||
//*****************************************************************************
|
||||
class Square;
|
||||
class Circle;
|
||||
class Triangle;
|
||||
|
||||
//*****************************************************************************
|
||||
// What classes do you want the visitors to handle?
|
||||
// Square will be passed by reference.
|
||||
// Circle will be passed by reference.
|
||||
// Triangle will be passed by const reference.
|
||||
//*****************************************************************************
|
||||
using DrawTypes = etl::type_list<Square&, Circle&, const Triangle&>;
|
||||
using DrawVisitorType = etl::visitor<DrawTypes>;
|
||||
|
||||
//*****************************************************************************
|
||||
// What classes do you want the visitors to handle?
|
||||
// Square will be passed by reference.
|
||||
// Triangle will be passed by const reference.
|
||||
//*****************************************************************************
|
||||
using LogTypes = etl::type_list<Square&, const Triangle&>;
|
||||
using LogVisitorType = etl::visitor<LogTypes>;
|
||||
|
||||
//*****************************************************************************
|
||||
// Base shape.
|
||||
//*****************************************************************************
|
||||
using VisitorTypes = etl::type_list<DrawVisitorType, LogVisitorType>;
|
||||
|
||||
class ShapeBase : public etl::visitable<VisitorTypes>
|
||||
{
|
||||
};
|
||||
|
||||
//*****************************************************************************
|
||||
// Square accepts draw & log visitors.
|
||||
//*****************************************************************************
|
||||
class Square : public ShapeBase
|
||||
{
|
||||
public:
|
||||
|
||||
void accept(DrawVisitorType& visitor)
|
||||
{
|
||||
visitor.visit(*this);
|
||||
}
|
||||
|
||||
void accept(LogVisitorType& visitor)
|
||||
{
|
||||
visitor.visit(*this);
|
||||
}
|
||||
};
|
||||
|
||||
//*****************************************************************************
|
||||
// Circle only accepts draw visitors.
|
||||
//*****************************************************************************
|
||||
class Circle : public ShapeBase
|
||||
{
|
||||
public:
|
||||
|
||||
void accept(DrawVisitorType& visitor)
|
||||
{
|
||||
visitor.visit(*this);
|
||||
}
|
||||
|
||||
void accept(LogVisitorType&)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//*****************************************************************************
|
||||
// Triangle accepts draw & log visitors.
|
||||
//*****************************************************************************
|
||||
class Triangle : public ShapeBase
|
||||
{
|
||||
public:
|
||||
|
||||
void accept(DrawVisitorType& visitor)
|
||||
{
|
||||
visitor.visit(*this);
|
||||
}
|
||||
|
||||
void accept(LogVisitorType& visitor)
|
||||
{
|
||||
visitor.visit(*this);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
// Generic other shapes.
|
||||
//*****************************************************************************
|
||||
template <const int ID, typename TVisitor>
|
||||
class Shape : public etl::visitable<TVisitor>
|
||||
{
|
||||
public:
|
||||
|
||||
void accept(TVisitor& visitor)
|
||||
{
|
||||
visitor.visit(*this);
|
||||
}
|
||||
};
|
||||
|
||||
//*****************************************************************************
|
||||
class DrawVisitor : public DrawVisitorType
|
||||
{
|
||||
public:
|
||||
|
||||
DrawVisitor()
|
||||
: square_called(false),
|
||||
circle_called(false),
|
||||
triangle_called(false)
|
||||
{
|
||||
}
|
||||
|
||||
void visit(Square&)
|
||||
{
|
||||
square_called = true;
|
||||
}
|
||||
|
||||
void visit(Circle&)
|
||||
{
|
||||
circle_called = true;
|
||||
}
|
||||
|
||||
void visit(const Triangle&)
|
||||
{
|
||||
triangle_called = true;
|
||||
}
|
||||
|
||||
bool square_called;
|
||||
bool circle_called;
|
||||
bool triangle_called;
|
||||
};
|
||||
|
||||
//*****************************************************************************
|
||||
class LogVisitor : public LogVisitorType
|
||||
{
|
||||
public:
|
||||
|
||||
LogVisitor()
|
||||
: square_called(false),
|
||||
circle_called(false),
|
||||
triangle_called(false)
|
||||
{
|
||||
}
|
||||
|
||||
void visit(Square&)
|
||||
{
|
||||
square_called = true;
|
||||
}
|
||||
|
||||
// SHOULD NEVER BE CALLED.
|
||||
void visit(Circle&)
|
||||
{
|
||||
circle_called = true;
|
||||
}
|
||||
|
||||
void visit(const Triangle&)
|
||||
{
|
||||
triangle_called = true;
|
||||
}
|
||||
|
||||
bool square_called;
|
||||
bool circle_called;
|
||||
bool triangle_called;
|
||||
};
|
||||
|
||||
namespace
|
||||
{
|
||||
SUITE(test_visitor)
|
||||
{
|
||||
//*************************************************************************
|
||||
TEST(test_two_visitors_three_visitables)
|
||||
{
|
||||
DrawVisitor draw_visitor;
|
||||
LogVisitor log_visitor;
|
||||
|
||||
Square square;
|
||||
Circle circle;
|
||||
Triangle triangle;
|
||||
|
||||
ShapeBase* pShapeBase;
|
||||
|
||||
CHECK_EQUAL(false, draw_visitor.square_called);
|
||||
CHECK_EQUAL(false, draw_visitor.circle_called);
|
||||
CHECK_EQUAL(false, draw_visitor.triangle_called);
|
||||
CHECK_EQUAL(false, log_visitor.square_called);
|
||||
CHECK_EQUAL(false, log_visitor.circle_called);
|
||||
CHECK_EQUAL(false, log_visitor.triangle_called);
|
||||
|
||||
square.accept(draw_visitor);
|
||||
square.accept(log_visitor);
|
||||
|
||||
CHECK_EQUAL(true, draw_visitor.square_called);
|
||||
CHECK_EQUAL(false, draw_visitor.circle_called);
|
||||
CHECK_EQUAL(false, draw_visitor.triangle_called);
|
||||
CHECK_EQUAL(true, log_visitor.square_called);
|
||||
CHECK_EQUAL(false, log_visitor.circle_called);
|
||||
CHECK_EQUAL(false, log_visitor.triangle_called);
|
||||
|
||||
circle.accept(draw_visitor);
|
||||
|
||||
CHECK_EQUAL(true, draw_visitor.square_called);
|
||||
CHECK_EQUAL(true, draw_visitor.circle_called);
|
||||
CHECK_EQUAL(false, draw_visitor.triangle_called);
|
||||
CHECK_EQUAL(true, log_visitor.square_called);
|
||||
CHECK_EQUAL(false, log_visitor.circle_called);
|
||||
CHECK_EQUAL(false, log_visitor.triangle_called);
|
||||
|
||||
pShapeBase = ▵
|
||||
pShapeBase->accept(draw_visitor);
|
||||
pShapeBase->accept(log_visitor);
|
||||
|
||||
CHECK_EQUAL(true, draw_visitor.square_called);
|
||||
CHECK_EQUAL(true, draw_visitor.circle_called);
|
||||
CHECK_EQUAL(true, draw_visitor.triangle_called);
|
||||
CHECK_EQUAL(true, log_visitor.square_called);
|
||||
CHECK_EQUAL(false, log_visitor.circle_called);
|
||||
CHECK_EQUAL(true, log_visitor.triangle_called);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_1_visitor)
|
||||
{
|
||||
class AShape;
|
||||
class ShapeVisitor1 : public etl::visitor<AShape&>
|
||||
{
|
||||
void visit(AShape&) {}
|
||||
};
|
||||
|
||||
class AShape : public etl::visitable<ShapeVisitor1>
|
||||
{
|
||||
public:
|
||||
|
||||
void accept(ShapeVisitor1&) {}
|
||||
};
|
||||
|
||||
// This test just needs to compile without errors.
|
||||
CHECK(true);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_2_visitor)
|
||||
{
|
||||
class AShape;
|
||||
class ShapeVisitor1 : public etl::visitor<AShape&>
|
||||
{
|
||||
void visit(AShape&) {}
|
||||
};
|
||||
|
||||
class ShapeVisitor2 : public etl::visitor<AShape&>
|
||||
{
|
||||
void visit(AShape&) {}
|
||||
};
|
||||
|
||||
class AShape : public etl::visitable<ShapeVisitor1, ShapeVisitor2>
|
||||
{
|
||||
public:
|
||||
|
||||
void accept(ShapeVisitor1&) {}
|
||||
void accept(ShapeVisitor2&) {}
|
||||
};
|
||||
|
||||
// This test just needs to compile without errors.
|
||||
CHECK(true);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_3_visitor)
|
||||
{
|
||||
class AShape;
|
||||
class ShapeVisitor1 : public etl::visitor<AShape&>
|
||||
{
|
||||
void visit(AShape&) {}
|
||||
};
|
||||
|
||||
class ShapeVisitor2 : public etl::visitor<AShape&>
|
||||
{
|
||||
void visit(AShape&) {}
|
||||
};
|
||||
|
||||
class ShapeVisitor3 : public etl::visitor<AShape&>
|
||||
{
|
||||
void visit(AShape&) {}
|
||||
};
|
||||
|
||||
class AShape : public etl::visitable<ShapeVisitor1, ShapeVisitor2, ShapeVisitor3>
|
||||
{
|
||||
public:
|
||||
|
||||
void accept(ShapeVisitor1&) {}
|
||||
void accept(ShapeVisitor2&) {}
|
||||
void accept(ShapeVisitor3&) {}
|
||||
};
|
||||
|
||||
// This test just needs to compile without errors.
|
||||
CHECK(true);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_4_visitor)
|
||||
{
|
||||
class AShape;
|
||||
class ShapeVisitor1 : public etl::visitor<AShape&>
|
||||
{
|
||||
void visit(AShape&) {}
|
||||
};
|
||||
|
||||
class ShapeVisitor2 : public etl::visitor<AShape&>
|
||||
{
|
||||
void visit(AShape&) {}
|
||||
};
|
||||
|
||||
class ShapeVisitor3 : public etl::visitor<AShape&>
|
||||
{
|
||||
void visit(AShape&) {}
|
||||
};
|
||||
|
||||
class ShapeVisitor4 : public etl::visitor<AShape&>
|
||||
{
|
||||
void visit(AShape&) {}
|
||||
};
|
||||
|
||||
using ShapeVisitorTypes = etl::type_list<ShapeVisitor1, ShapeVisitor2, ShapeVisitor3, ShapeVisitor4>;
|
||||
|
||||
class AShape : public etl::visitable<ShapeVisitorTypes>
|
||||
{
|
||||
public:
|
||||
|
||||
void accept(ShapeVisitor1&) {}
|
||||
void accept(ShapeVisitor2&) {}
|
||||
void accept(ShapeVisitor3&) {}
|
||||
void accept(ShapeVisitor4&) {}
|
||||
};
|
||||
|
||||
// This test just needs to compile without errors.
|
||||
CHECK(true);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_1_visitable)
|
||||
{
|
||||
class ShapeVisitor : public etl::visitor <Shape<1, ShapeVisitor> >
|
||||
{
|
||||
public:
|
||||
|
||||
void visit(Shape<1, ShapeVisitor>) {}
|
||||
};
|
||||
|
||||
// This test just needs to compile without errors.
|
||||
CHECK(true);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_2_visitable)
|
||||
{
|
||||
class ShapeVisitor : public etl::visitor <Shape<1, ShapeVisitor>, Shape<2, ShapeVisitor> >
|
||||
{
|
||||
public:
|
||||
|
||||
void visit(Shape<1, ShapeVisitor>) {}
|
||||
void visit(Shape<2, ShapeVisitor>) {}
|
||||
};
|
||||
|
||||
// This test just needs to compile without errors.
|
||||
CHECK(true);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_3_visitable)
|
||||
{
|
||||
class ShapeVisitor : public etl::visitor <Shape<1, ShapeVisitor>, Shape<2, ShapeVisitor>, Shape<3, ShapeVisitor> >
|
||||
{
|
||||
public:
|
||||
|
||||
void visit(Shape<1, ShapeVisitor>) {}
|
||||
void visit(Shape<2, ShapeVisitor>) {}
|
||||
void visit(Shape<3, ShapeVisitor>) {}
|
||||
};
|
||||
|
||||
// This test just needs to compile without errors.
|
||||
CHECK(true);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_4_visitable)
|
||||
{
|
||||
class ShapeVisitor : public etl::visitor <Shape<1, ShapeVisitor>, Shape<2, ShapeVisitor>, Shape<3, ShapeVisitor>, Shape<4, ShapeVisitor> >
|
||||
{
|
||||
public:
|
||||
|
||||
void visit(Shape<1, ShapeVisitor>) {}
|
||||
void visit(Shape<2, ShapeVisitor>) {}
|
||||
void visit(Shape<3, ShapeVisitor>) {}
|
||||
void visit(Shape<4, ShapeVisitor>) {}
|
||||
};
|
||||
|
||||
// This test just needs to compile without errors.
|
||||
CHECK(true);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_5_visitable)
|
||||
{
|
||||
class ShapeVisitor : public etl::visitor <Shape<1, ShapeVisitor>, Shape<2, ShapeVisitor>, Shape<3, ShapeVisitor>, Shape<4, ShapeVisitor>,
|
||||
Shape<5, ShapeVisitor> >
|
||||
{
|
||||
public:
|
||||
|
||||
void visit(Shape<1, ShapeVisitor>) {}
|
||||
void visit(Shape<2, ShapeVisitor>) {}
|
||||
void visit(Shape<3, ShapeVisitor>) {}
|
||||
void visit(Shape<4, ShapeVisitor>) {}
|
||||
void visit(Shape<5, ShapeVisitor>) {}
|
||||
};
|
||||
|
||||
// This test just needs to compile without errors.
|
||||
CHECK(true);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_6_visitable)
|
||||
{
|
||||
class ShapeVisitor : public etl::visitor <Shape<1, ShapeVisitor>, Shape<2, ShapeVisitor>, Shape<3, ShapeVisitor>, Shape<4, ShapeVisitor>,
|
||||
Shape<5, ShapeVisitor>, Shape<6, ShapeVisitor> >
|
||||
{
|
||||
public:
|
||||
|
||||
void visit(Shape<1, ShapeVisitor>) {}
|
||||
void visit(Shape<2, ShapeVisitor>) {}
|
||||
void visit(Shape<3, ShapeVisitor>) {}
|
||||
void visit(Shape<4, ShapeVisitor>) {}
|
||||
void visit(Shape<5, ShapeVisitor>) {}
|
||||
void visit(Shape<6, ShapeVisitor>) {}
|
||||
};
|
||||
|
||||
// This test just needs to compile without errors.
|
||||
CHECK(true);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_7_visitable)
|
||||
{
|
||||
class ShapeVisitor : public etl::visitor <Shape<1, ShapeVisitor>, Shape<2, ShapeVisitor>, Shape<3, ShapeVisitor>, Shape<4, ShapeVisitor>,
|
||||
Shape<5, ShapeVisitor>, Shape<6, ShapeVisitor>, Shape<7, ShapeVisitor> >
|
||||
{
|
||||
public:
|
||||
|
||||
void visit(Shape<1, ShapeVisitor>) {}
|
||||
void visit(Shape<2, ShapeVisitor>) {}
|
||||
void visit(Shape<3, ShapeVisitor>) {}
|
||||
void visit(Shape<4, ShapeVisitor>) {}
|
||||
void visit(Shape<5, ShapeVisitor>) {}
|
||||
void visit(Shape<6, ShapeVisitor>) {}
|
||||
void visit(Shape<7, ShapeVisitor>) {}
|
||||
};
|
||||
|
||||
// This test just needs to compile without errors.
|
||||
CHECK(true);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_8_visitable)
|
||||
{
|
||||
class ShapeVisitor : public etl::visitor <Shape<1, ShapeVisitor>, Shape<2, ShapeVisitor>, Shape<3, ShapeVisitor>, Shape<4, ShapeVisitor>,
|
||||
Shape<5, ShapeVisitor>, Shape<6, ShapeVisitor>, Shape<7, ShapeVisitor>, Shape<8, ShapeVisitor> >
|
||||
{
|
||||
public:
|
||||
|
||||
void visit(Shape<1, ShapeVisitor>) {}
|
||||
void visit(Shape<2, ShapeVisitor>) {}
|
||||
void visit(Shape<3, ShapeVisitor>) {}
|
||||
void visit(Shape<4, ShapeVisitor>) {}
|
||||
void visit(Shape<5, ShapeVisitor>) {}
|
||||
void visit(Shape<6, ShapeVisitor>) {}
|
||||
void visit(Shape<7, ShapeVisitor>) {}
|
||||
void visit(Shape<8, ShapeVisitor>) {}
|
||||
};
|
||||
|
||||
// This test just needs to compile without errors.
|
||||
CHECK(true);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_9_visitable)
|
||||
{
|
||||
class ShapeVisitor : public etl::visitor <Shape<1, ShapeVisitor>, Shape<2, ShapeVisitor>, Shape<3, ShapeVisitor>, Shape<4, ShapeVisitor>,
|
||||
Shape<5, ShapeVisitor>, Shape<6, ShapeVisitor>, Shape<7, ShapeVisitor>, Shape<8, ShapeVisitor>,
|
||||
Shape<9, ShapeVisitor> >
|
||||
{
|
||||
public:
|
||||
|
||||
void visit(Shape<1, ShapeVisitor>) {}
|
||||
void visit(Shape<2, ShapeVisitor>) {}
|
||||
void visit(Shape<3, ShapeVisitor>) {}
|
||||
void visit(Shape<4, ShapeVisitor>) {}
|
||||
void visit(Shape<5, ShapeVisitor>) {}
|
||||
void visit(Shape<6, ShapeVisitor>) {}
|
||||
void visit(Shape<7, ShapeVisitor>) {}
|
||||
void visit(Shape<8, ShapeVisitor>) {}
|
||||
void visit(Shape<9, ShapeVisitor>) {}
|
||||
};
|
||||
|
||||
// This test just needs to compile without errors.
|
||||
CHECK(true);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_10_visitable)
|
||||
{
|
||||
class ShapeVisitor : public etl::visitor <Shape<1, ShapeVisitor>, Shape<2, ShapeVisitor>, Shape<3, ShapeVisitor>, Shape<4, ShapeVisitor>,
|
||||
Shape<5, ShapeVisitor>, Shape<6, ShapeVisitor>, Shape<7, ShapeVisitor>, Shape<8, ShapeVisitor>,
|
||||
Shape<9, ShapeVisitor>, Shape<10, ShapeVisitor> >
|
||||
{
|
||||
public:
|
||||
|
||||
void visit(Shape<1, ShapeVisitor>) {}
|
||||
void visit(Shape<2, ShapeVisitor>) {}
|
||||
void visit(Shape<3, ShapeVisitor>) {}
|
||||
void visit(Shape<4, ShapeVisitor>) {}
|
||||
void visit(Shape<5, ShapeVisitor>) {}
|
||||
void visit(Shape<6, ShapeVisitor>) {}
|
||||
void visit(Shape<7, ShapeVisitor>) {}
|
||||
void visit(Shape<8, ShapeVisitor>) {}
|
||||
void visit(Shape<9, ShapeVisitor>) {}
|
||||
void visit(Shape<10, ShapeVisitor>) {}
|
||||
};
|
||||
|
||||
// This test just needs to compile without errors.
|
||||
CHECK(true);
|
||||
}
|
||||
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_11_visitable)
|
||||
{
|
||||
class ShapeVisitor : public etl::visitor <Shape<1, ShapeVisitor>, Shape<2, ShapeVisitor>, Shape<3, ShapeVisitor>, Shape<4, ShapeVisitor>,
|
||||
Shape<5, ShapeVisitor>, Shape<6, ShapeVisitor>, Shape<7, ShapeVisitor>, Shape<8, ShapeVisitor>,
|
||||
Shape<9, ShapeVisitor>, Shape<10, ShapeVisitor>, Shape<11, ShapeVisitor> >
|
||||
{
|
||||
public:
|
||||
|
||||
void visit(Shape<1, ShapeVisitor>) {}
|
||||
void visit(Shape<2, ShapeVisitor>) {}
|
||||
void visit(Shape<3, ShapeVisitor>) {}
|
||||
void visit(Shape<4, ShapeVisitor>) {}
|
||||
void visit(Shape<5, ShapeVisitor>) {}
|
||||
void visit(Shape<6, ShapeVisitor>) {}
|
||||
void visit(Shape<7, ShapeVisitor>) {}
|
||||
void visit(Shape<8, ShapeVisitor>) {}
|
||||
void visit(Shape<9, ShapeVisitor>) {}
|
||||
void visit(Shape<10, ShapeVisitor>) {}
|
||||
void visit(Shape<11, ShapeVisitor>) {}
|
||||
};
|
||||
|
||||
// This test just needs to compile without errors.
|
||||
CHECK(true);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_12_visitable)
|
||||
{
|
||||
class ShapeVisitor : public etl::visitor <Shape<1, ShapeVisitor>, Shape<2, ShapeVisitor>, Shape<3, ShapeVisitor>, Shape<4, ShapeVisitor>,
|
||||
Shape<5, ShapeVisitor>, Shape<6, ShapeVisitor>, Shape<7, ShapeVisitor>, Shape<8, ShapeVisitor>,
|
||||
Shape<9, ShapeVisitor>, Shape<10, ShapeVisitor>, Shape<11, ShapeVisitor>, Shape<12, ShapeVisitor> >
|
||||
{
|
||||
public:
|
||||
|
||||
void visit(Shape<1, ShapeVisitor>) {}
|
||||
void visit(Shape<2, ShapeVisitor>) {}
|
||||
void visit(Shape<3, ShapeVisitor>) {}
|
||||
void visit(Shape<4, ShapeVisitor>) {}
|
||||
void visit(Shape<5, ShapeVisitor>) {}
|
||||
void visit(Shape<6, ShapeVisitor>) {}
|
||||
void visit(Shape<7, ShapeVisitor>) {}
|
||||
void visit(Shape<8, ShapeVisitor>) {}
|
||||
void visit(Shape<9, ShapeVisitor>) {}
|
||||
void visit(Shape<10, ShapeVisitor>) {}
|
||||
void visit(Shape<11, ShapeVisitor>) {}
|
||||
void visit(Shape<12, ShapeVisitor>) {}
|
||||
};
|
||||
|
||||
// This test just needs to compile without errors.
|
||||
CHECK(true);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_13_visitable)
|
||||
{
|
||||
class ShapeVisitor : public etl::visitor <Shape<1, ShapeVisitor>, Shape<2, ShapeVisitor>, Shape<3, ShapeVisitor>, Shape<4, ShapeVisitor>,
|
||||
Shape<5, ShapeVisitor>, Shape<6, ShapeVisitor>, Shape<7, ShapeVisitor>, Shape<8, ShapeVisitor>,
|
||||
Shape<9, ShapeVisitor>, Shape<10, ShapeVisitor>, Shape<11, ShapeVisitor>, Shape<12, ShapeVisitor>,
|
||||
Shape<13, ShapeVisitor> >
|
||||
{
|
||||
public:
|
||||
|
||||
void visit(Shape<1, ShapeVisitor>) {}
|
||||
void visit(Shape<2, ShapeVisitor>) {}
|
||||
void visit(Shape<3, ShapeVisitor>) {}
|
||||
void visit(Shape<4, ShapeVisitor>) {}
|
||||
void visit(Shape<5, ShapeVisitor>) {}
|
||||
void visit(Shape<6, ShapeVisitor>) {}
|
||||
void visit(Shape<7, ShapeVisitor>) {}
|
||||
void visit(Shape<8, ShapeVisitor>) {}
|
||||
void visit(Shape<9, ShapeVisitor>) {}
|
||||
void visit(Shape<10, ShapeVisitor>) {}
|
||||
void visit(Shape<11, ShapeVisitor>) {}
|
||||
void visit(Shape<12, ShapeVisitor>) {}
|
||||
void visit(Shape<13, ShapeVisitor>) {}
|
||||
};
|
||||
|
||||
// This test just needs to compile without errors.
|
||||
CHECK(true);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_14_visitable)
|
||||
{
|
||||
class ShapeVisitor : public etl::visitor <Shape<1, ShapeVisitor>, Shape<2, ShapeVisitor>, Shape<3, ShapeVisitor>, Shape<4, ShapeVisitor>,
|
||||
Shape<5, ShapeVisitor>, Shape<6, ShapeVisitor>, Shape<7, ShapeVisitor>, Shape<8, ShapeVisitor>,
|
||||
Shape<9, ShapeVisitor>, Shape<10, ShapeVisitor>, Shape<11, ShapeVisitor>, Shape<12, ShapeVisitor>,
|
||||
Shape<13, ShapeVisitor>, Shape<14, ShapeVisitor> >
|
||||
{
|
||||
public:
|
||||
|
||||
void visit(Shape<1, ShapeVisitor>) {}
|
||||
void visit(Shape<2, ShapeVisitor>) {}
|
||||
void visit(Shape<3, ShapeVisitor>) {}
|
||||
void visit(Shape<4, ShapeVisitor>) {}
|
||||
void visit(Shape<5, ShapeVisitor>) {}
|
||||
void visit(Shape<6, ShapeVisitor>) {}
|
||||
void visit(Shape<7, ShapeVisitor>) {}
|
||||
void visit(Shape<8, ShapeVisitor>) {}
|
||||
void visit(Shape<9, ShapeVisitor>) {}
|
||||
void visit(Shape<10, ShapeVisitor>) {}
|
||||
void visit(Shape<11, ShapeVisitor>) {}
|
||||
void visit(Shape<12, ShapeVisitor>) {}
|
||||
void visit(Shape<13, ShapeVisitor>) {}
|
||||
void visit(Shape<14, ShapeVisitor>) {}
|
||||
};
|
||||
|
||||
// This test just needs to compile without errors.
|
||||
CHECK(true);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_15_visitable)
|
||||
{
|
||||
class ShapeVisitor : public etl::visitor <Shape<1, ShapeVisitor>, Shape<2, ShapeVisitor>, Shape<3, ShapeVisitor>, Shape<4, ShapeVisitor>,
|
||||
Shape<5, ShapeVisitor>, Shape<6, ShapeVisitor>, Shape<7, ShapeVisitor>, Shape<8, ShapeVisitor>,
|
||||
Shape<9, ShapeVisitor>, Shape<10, ShapeVisitor>, Shape<11, ShapeVisitor>, Shape<12, ShapeVisitor>,
|
||||
Shape<13, ShapeVisitor>, Shape<14, ShapeVisitor>, Shape<15, ShapeVisitor> >
|
||||
{
|
||||
public:
|
||||
|
||||
void visit(Shape<1, ShapeVisitor>) {}
|
||||
void visit(Shape<2, ShapeVisitor>) {}
|
||||
void visit(Shape<3, ShapeVisitor>) {}
|
||||
void visit(Shape<4, ShapeVisitor>) {}
|
||||
void visit(Shape<5, ShapeVisitor>) {}
|
||||
void visit(Shape<6, ShapeVisitor>) {}
|
||||
void visit(Shape<7, ShapeVisitor>) {}
|
||||
void visit(Shape<8, ShapeVisitor>) {}
|
||||
void visit(Shape<9, ShapeVisitor>) {}
|
||||
void visit(Shape<10, ShapeVisitor>) {}
|
||||
void visit(Shape<11, ShapeVisitor>) {}
|
||||
void visit(Shape<12, ShapeVisitor>) {}
|
||||
void visit(Shape<13, ShapeVisitor>) {}
|
||||
void visit(Shape<14, ShapeVisitor>) {}
|
||||
void visit(Shape<15, ShapeVisitor>) {}
|
||||
};
|
||||
|
||||
// This test just needs to compile without errors.
|
||||
CHECK(true);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_16_visitable)
|
||||
{
|
||||
class ShapeVisitor : public etl::visitor <Shape<1, ShapeVisitor>, Shape<2, ShapeVisitor>, Shape<3, ShapeVisitor>, Shape<4, ShapeVisitor>,
|
||||
Shape<5, ShapeVisitor>, Shape<6, ShapeVisitor>, Shape<7, ShapeVisitor>, Shape<8, ShapeVisitor>,
|
||||
Shape<9, ShapeVisitor>, Shape<10, ShapeVisitor>, Shape<11, ShapeVisitor>, Shape<12, ShapeVisitor>,
|
||||
Shape<13, ShapeVisitor>, Shape<14, ShapeVisitor>, Shape<15, ShapeVisitor>, Shape<16, ShapeVisitor> >
|
||||
{
|
||||
public:
|
||||
|
||||
void visit(Shape<1, ShapeVisitor>) {}
|
||||
void visit(Shape<2, ShapeVisitor>) {}
|
||||
void visit(Shape<3, ShapeVisitor>) {}
|
||||
void visit(Shape<4, ShapeVisitor>) {}
|
||||
void visit(Shape<5, ShapeVisitor>) {}
|
||||
void visit(Shape<6, ShapeVisitor>) {}
|
||||
void visit(Shape<7, ShapeVisitor>) {}
|
||||
void visit(Shape<8, ShapeVisitor>) {}
|
||||
void visit(Shape<9, ShapeVisitor>) {}
|
||||
void visit(Shape<10, ShapeVisitor>) {}
|
||||
void visit(Shape<11, ShapeVisitor>) {}
|
||||
void visit(Shape<12, ShapeVisitor>) {}
|
||||
void visit(Shape<13, ShapeVisitor>) {}
|
||||
void visit(Shape<14, ShapeVisitor>) {}
|
||||
void visit(Shape<15, ShapeVisitor>) {}
|
||||
void visit(Shape<16, ShapeVisitor>) {}
|
||||
};
|
||||
|
||||
// This test just needs to compile without errors.
|
||||
CHECK(true);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
struct NotVisitor {};
|
||||
|
||||
TEST(test_is_visitor)
|
||||
{
|
||||
#if ETL_USING_CPP17
|
||||
CHECK_TRUE(etl::is_visitor_v<DrawVisitor>);
|
||||
CHECK_TRUE(etl::is_visitor_v<LogVisitor>);
|
||||
CHECK_FALSE(etl::is_visitor_v<NotVisitor>);
|
||||
#else
|
||||
CHECK_TRUE(etl::is_visitor<DrawVisitor>::value);
|
||||
CHECK_TRUE(etl::is_visitor<LogVisitor>::value);
|
||||
CHECK_FALSE(etl::is_visitor<NotVisitor>::value);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@ -10357,9 +10357,11 @@
|
||||
<ClCompile Include="..\test_math_functions.cpp" />
|
||||
<ClCompile Include="..\test_message.cpp" />
|
||||
<ClCompile Include="..\test_message_broker.cpp" />
|
||||
<ClCompile Include="..\test_message_router_with_type_list.cpp" />
|
||||
<ClCompile Include="..\test_not_null_pointer.cpp" />
|
||||
<ClCompile Include="..\test_not_null_pointer_constexpr.cpp" />
|
||||
<ClCompile Include="..\test_not_null_unique_pointer.cpp" />
|
||||
<ClCompile Include="..\test_observer_with_type_list.cpp" />
|
||||
<ClCompile Include="..\test_poly_span_dynamic_extent.cpp" />
|
||||
<ClCompile Include="..\test_poly_span_fixed_extent.cpp" />
|
||||
<ClCompile Include="..\test_pseudo_moving_average.cpp" />
|
||||
@ -11433,6 +11435,7 @@
|
||||
<ClCompile Include="..\test_vector_pointer_external_buffer.cpp" />
|
||||
<ClCompile Include="..\test_visitor.cpp" />
|
||||
<ClCompile Include="..\test_string_stream_wchar_t.cpp" />
|
||||
<ClCompile Include="..\test_visitor_with_type_list.cpp" />
|
||||
<ClCompile Include="..\test_xor_checksum.cpp" />
|
||||
<ClCompile Include="..\test_xor_rotate_checksum.cpp" />
|
||||
<ClCompile Include="..\unittest++\AssertException.cpp" />
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user