refactor: Update CMake build system and streamline Core object serialization and property handling.

This commit is contained in:
AndreaRigoni
2026-02-21 16:16:28 +00:00
parent 7ded15d596
commit d56758d0b3
24 changed files with 830 additions and 1056 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -1,10 +1,9 @@
set(HEADERS Options.h
StaticInterface.h)
set(HEADERS Archives.h Array.h Collection.h Debug.h Export.h Function.h Macros.h Mpl.h Object.h Options.h Serializable.h Signal.h Singleton.h SmartPointer.h StaticInterface.h StringReader.h Types.h Uuid.h Vector.h)
set(SOURCES Options.cpp)
set(SOURCES Archives.cpp Debug.cpp Object.cpp Options.cpp Serializable.cpp Signal.cpp Uuid.cpp)
set(LIBRARIES ${Boost_PROGRAM_OPTIONS_LIBRARY})
set(LIBRARIES Boost::program_options)
set(libname ${PACKAGE_LIBPREFIX}Core)
set(ULIB_SHARED_LIBRARIES ${ULIB_SHARED_LIBRARIES} ${libname} PARENT_SCOPE)
@@ -23,5 +22,7 @@ install(TARGETS ${libname}
install(FILES ${HEADERS} DESTINATION ${INSTALL_INC_DIR}/Core)
if(BUILD_TESTING)
include(uLibTargetMacros)
add_subdirectory(testing)
endif()

View File

@@ -23,95 +23,85 @@
//////////////////////////////////////////////////////////////////////////////*/
#ifndef U_CORE_EXPORT_H
#define U_CORE_EXPORT_H
#include <utility>
#include <cstddef> // NULL
#include <iostream>
#include <utility>
#include <boost/config.hpp>
#include <boost/static_assert.hpp>
#include <boost/preprocessor/stringize.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_polymorphic.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/mpl/and.hpp>
#include <boost/mpl/not.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/not.hpp>
#include <boost/serialization/extended_type_info.hpp> // for guid_defined only
#include <boost/serialization/static_warning.hpp>
#include <boost/serialization/assume_abstract.hpp>
#include <boost/serialization/extended_type_info.hpp> // for guid_defined only
#include <boost/serialization/force_include.hpp>
#include <boost/serialization/singleton.hpp>
#include <boost/serialization/static_warning.hpp>
#include <boost/archive/detail/register_archive.hpp>
#include "Core/Archives.h"
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
namespace uLib {
namespace Archive {
namespace detail {
namespace extra_detail {
template<class T>
struct guid_initializer
{
void export_guid(mpl::false_) const {
// generates the statically-initialized objects whose constructors
// register the information allowing serialization of T objects
// through pointers to their base classes.
boost::archive::detail::
instantiate_ptr_serialization((T*)0, 0,
uLib::Archive::detail::adl_tag());
}
void export_guid(mpl::true_) const {
}
guid_initializer const & export_guid() const {
BOOST_STATIC_WARNING(boost::is_polymorphic< T >::value);
// note: exporting an abstract base class will have no effect
// and cannot be used to instantitiate serialization code
// (one might be using this in a DLL to instantiate code)
//BOOST_STATIC_WARNING(! boost::serialization::is_abstract< T >::value);
export_guid(boost::serialization::is_abstract< T >());
return *this;
}
template <class T> struct guid_initializer {
void export_guid(boost::mpl::false_) const {
// generates the statically-initialized objects whose constructors
// register the information allowing serialization of T objects
// through pointers to their base classes.
boost::archive::detail::instantiate_ptr_serialization(
(T *)0, 0, uLib::Archive::detail::adl_tag());
}
void export_guid(boost::mpl::true_) const {}
guid_initializer const &export_guid() const {
BOOST_STATIC_WARNING(boost::is_polymorphic<T>::value);
// note: exporting an abstract base class will have no effect
// and cannot be used to instantitiate serialization code
// (one might be using this in a DLL to instantiate code)
// BOOST_STATIC_WARNING(! boost::serialization::is_abstract< T >::value);
export_guid(boost::serialization::is_abstract<T>());
return *this;
}
};
template<typename T>
struct init_guid;
template <typename T> struct init_guid;
} // anonymous
} // namespace extra_detail
} // namespace detail
} // namespace Archive
} // namespace uLib
#define ULIB_CLASS_EXPORT_IMPLEMENT(T) \
namespace uLib { \
namespace Archive { \
namespace detail { \
namespace extra_detail { \
template<> \
struct init_guid< T > { \
static guid_initializer< T > const & g; \
}; \
guid_initializer< T > const & init_guid< T >::g = \
::boost::serialization::singleton< \
guid_initializer< T > \
>::get_mutable_instance().export_guid(); \
}}}} \
/**/
#define ULIB_CLASS_EXPORT_IMPLEMENT(T) \
namespace uLib { \
namespace Archive { \
namespace detail { \
namespace extra_detail { \
template <> struct init_guid<T> { \
static guid_initializer<T> const &g; \
}; \
guid_initializer<T> const &init_guid<T>::g = \
::boost::serialization::singleton< \
guid_initializer<T>>::get_mutable_instance() \
.export_guid(); \
} \
} \
} \
} \
/**/
#endif // EXPORT_H

View File

@@ -110,11 +110,13 @@ bool Object::addSignalImpl(SignalBase *sig, GenericMFPtr fptr,
const char *name) {
ObjectPrivate::Signal s = {fptr, std::string(name), sig};
d->sigv.push_back(s);
return true;
}
bool Object::addSlotImpl(GenericMFPtr fptr, const char *name) {
ObjectPrivate::Slot s = {fptr, std::string(name)};
d->slov.push_back(s);
return true;
}
SignalBase *Object::findSignalImpl(const GenericMFPtr &fptr) const {

View File

@@ -107,6 +107,7 @@ public:
// if(sig && slo)
// return Object::connect(sig,slo->operator ()(),receiver);
// else return false;
return false;
}
// Qt5 style connector //
@@ -119,11 +120,13 @@ public:
typename FunctionPointer<Func2>::SignalSignature>
SigT;
ConnectSignal(sigb, slof, receiver);
return true;
}
template <typename FuncT>
static inline bool connect(SignalBase *sigb, FuncT slof, Object *receiver) {
ConnectSignal(sigb, slof, receiver);
return true;
}
template <typename FuncT>
@@ -139,7 +142,7 @@ public:
}
template <typename FuncT> inline bool addSlot(FuncT fun, const char *name) {
this->addSlotImpl(GenericMFPtr(fun), name);
return this->addSlotImpl(GenericMFPtr(fun), name);
}
template <typename FuncT>

View File

@@ -23,21 +23,19 @@
//////////////////////////////////////////////////////////////////////////////*/
#ifndef U_CORE_SIGNAL_H
#define U_CORE_SIGNAL_H
#include <boost/typeof/typeof.hpp>
#include <boost/signals2/signal.hpp>
#include <boost/signals2/slot.hpp>
#include <boost/signals2/signal_type.hpp>
#include <boost/signals2/slot.hpp>
#include "Function.h"
#include <boost/bind/bind.hpp>
using namespace boost::placeholders;
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
@@ -48,12 +46,12 @@
#define slots
#define signals /*virtual void init_signals();*/ public
#define emit
#define SLOT(a) BOOST_STRINGIZE(a)
#define SIGNAL(a) BOOST_STRINGIZE(a)
#define SLOT(a) BOOST_STRINGIZE(a)
#define SIGNAL(a) BOOST_STRINGIZE(a)
#define _ULIB_DETAIL_SIGNAL_EMIT(_name,...) \
static BOOST_AUTO(sig,this->findOrAddSignal(&_name)); \
sig->operator()(__VA_ARGS__);
#define _ULIB_DETAIL_SIGNAL_EMIT(_name, ...) \
static BOOST_AUTO(sig, this->findOrAddSignal(&_name)); \
sig->operator()(__VA_ARGS__);
/**
* Utility macro to implement signal emission implementa una delle seguenti:
@@ -66,103 +64,105 @@
* // cast automatico //
* static BOOST_AUTO(sig,this->findOrAddSignal(&Ob1::V0));
* sig->operator()();
*/
#define ULIB_SIGNAL_EMIT(_name,...) _ULIB_DETAIL_SIGNAL_EMIT(_name,__VA_ARGS__)
*/
#define ULIB_SIGNAL_EMIT(_name, ...) \
_ULIB_DETAIL_SIGNAL_EMIT(_name, __VA_ARGS__)
namespace uLib {
// A boost::signal wrapper structure ///////////////////////////////////////////
// TODO ...
typedef boost::signals2::signal_base SignalBase;
template <typename T>
struct Signal {
typedef boost::signals2::signal<T> type;
template <typename T> struct Signal {
typedef boost::signals2::signal<T> type;
};
////////////////////////////////////////////////////////////////////////////////
namespace detail {
template <typename FuncT, int arity> struct ConnectSignal {};
template <typename FuncT, int arity>
struct ConnectSignal {};
template <typename FuncT>
struct ConnectSignal< FuncT, 0 > {
static void connect(SignalBase *sigb, FuncT slof, typename FunctionPointer<FuncT>::Object *receiver) {
typedef typename Signal<typename FunctionPointer<FuncT>::SignalSignature>::type SigT;
reinterpret_cast<SigT*>(sigb)->connect(slof);
}
template <typename FuncT> struct ConnectSignal<FuncT, 0> {
static void connect(SignalBase *sigb, FuncT slof,
typename FunctionPointer<FuncT>::Object *receiver) {
typedef
typename Signal<typename FunctionPointer<FuncT>::SignalSignature>::type
SigT;
reinterpret_cast<SigT *>(sigb)->connect(slof);
}
};
template <typename FuncT>
struct ConnectSignal< FuncT, 1 > {
static void connect(SignalBase *sigb, FuncT slof, typename FunctionPointer<FuncT>::Object *receiver) {
typedef typename Signal<typename FunctionPointer<FuncT>::SignalSignature>::type SigT;
reinterpret_cast<SigT*>(sigb)->connect(boost::bind(slof,receiver));
}
template <typename FuncT> struct ConnectSignal<FuncT, 1> {
static void connect(SignalBase *sigb, FuncT slof,
typename FunctionPointer<FuncT>::Object *receiver) {
typedef
typename Signal<typename FunctionPointer<FuncT>::SignalSignature>::type
SigT;
reinterpret_cast<SigT *>(sigb)->connect(boost::bind(slof, receiver));
}
};
template <typename FuncT>
struct ConnectSignal< FuncT, 2 > {
static void connect(SignalBase *sigb, FuncT slof, typename FunctionPointer<FuncT>::Object *receiver) {
typedef typename Signal<typename FunctionPointer<FuncT>::SignalSignature>::type SigT;
reinterpret_cast<SigT*>(sigb)->connect(boost::bind(slof,receiver,_1));
}
template <typename FuncT> struct ConnectSignal<FuncT, 2> {
static void connect(SignalBase *sigb, FuncT slof,
typename FunctionPointer<FuncT>::Object *receiver) {
typedef
typename Signal<typename FunctionPointer<FuncT>::SignalSignature>::type
SigT;
reinterpret_cast<SigT *>(sigb)->connect(boost::bind(slof, receiver, _1));
}
};
template <typename FuncT>
struct ConnectSignal< FuncT, 3 > {
static void connect(SignalBase *sigb, FuncT slof, typename FunctionPointer<FuncT>::Object *receiver) {
typedef typename Signal<typename FunctionPointer<FuncT>::SignalSignature>::type SigT;
reinterpret_cast<SigT*>(sigb)->connect(boost::bind(slof,receiver,_1,_2));
}
template <typename FuncT> struct ConnectSignal<FuncT, 3> {
static void connect(SignalBase *sigb, FuncT slof,
typename FunctionPointer<FuncT>::Object *receiver) {
typedef
typename Signal<typename FunctionPointer<FuncT>::SignalSignature>::type
SigT;
reinterpret_cast<SigT *>(sigb)->connect(
boost::bind(slof, receiver, _1, _2));
}
};
template <typename FuncT>
struct ConnectSignal< FuncT, 4 > {
static void connect(SignalBase *sigb, FuncT slof, typename FunctionPointer<FuncT>::Object *receiver) {
typedef typename Signal<typename FunctionPointer<FuncT>::SignalSignature>::type SigT;
reinterpret_cast<SigT*>(sigb)->connect(boost::bind(slof,receiver,_1,_2,_3));
}
template <typename FuncT> struct ConnectSignal<FuncT, 4> {
static void connect(SignalBase *sigb, FuncT slof,
typename FunctionPointer<FuncT>::Object *receiver) {
typedef
typename Signal<typename FunctionPointer<FuncT>::SignalSignature>::type
SigT;
reinterpret_cast<SigT *>(sigb)->connect(
boost::bind(slof, receiver, _1, _2, _3));
}
};
template <typename FuncT>
struct ConnectSignal< FuncT, 5 > {
static void connect(SignalBase *sigb, FuncT slof, typename FunctionPointer<FuncT>::Object *receiver) {
typedef typename Signal<typename FunctionPointer<FuncT>::SignalSignature>::type SigT;
reinterpret_cast<SigT*>(sigb)->connect(boost::bind(slof,receiver,_1,_2,_3,_4));
}
template <typename FuncT> struct ConnectSignal<FuncT, 5> {
static void connect(SignalBase *sigb, FuncT slof,
typename FunctionPointer<FuncT>::Object *receiver) {
typedef
typename Signal<typename FunctionPointer<FuncT>::SignalSignature>::type
SigT;
reinterpret_cast<SigT *>(sigb)->connect(
boost::bind(slof, receiver, _1, _2, _3, _4));
}
};
} // namespace detail
} // detail
template <typename FuncT>
SignalBase *NewSignal(FuncT f) {
// seems to work wow !
return new Signal<void()>::type;
template <typename FuncT> SignalBase *NewSignal(FuncT f) {
// seems to work wow !
return new Signal<void()>::type;
}
template <typename FuncT>
void ConnectSignal(SignalBase *sigb, FuncT slof, typename FunctionPointer<FuncT>::Object *receiver)
{
detail::ConnectSignal< FuncT, FunctionPointer<FuncT>::arity >::connect(sigb,slof,receiver);
void ConnectSignal(SignalBase *sigb, FuncT slof,
typename FunctionPointer<FuncT>::Object *receiver) {
detail::ConnectSignal<FuncT, FunctionPointer<FuncT>::arity>::connect(
sigb, slof, receiver);
}
} // uLib
} // namespace uLib
#endif // SIGNAL_H

View File

@@ -24,9 +24,8 @@ set( TESTS
set(LIBRARIES
${PACKAGE_LIBPREFIX}Core
${PACKAGE_LIBPREFIX}Math
${Boost_SERIALIZATION_LIBRARY}
${Boost_SIGNALS_LIBRARY}
${Boost_PROGRAM_OPTIONS_LIBRARY}
Boost::serialization
Boost::program_options
${ROOT_LIBRARIES}
)
uLib_add_tests(${uLib-module})
uLib_add_tests(Core)

View File

@@ -23,13 +23,10 @@
//////////////////////////////////////////////////////////////////////////////*/
#include <iostream>
#include <fstream>
#include <typeinfo>
#include <iostream>
#include <string>
#include <typeinfo>
#include "Core/Object.h"
@@ -37,78 +34,43 @@
using namespace uLib;
struct A : Object {
uLibTypeMacro(A,Object)
A() : numa(5552368) {}
int numa;
struct A : Object {
uLibTypeMacro(A, Object) A() : numa(5552368) {}
int numa;
};
ULIB_SERIALIZABLE_OBJECT(A)
ULIB_SERIALIZE_OBJECT(A,Object) {
ar & AR(numa);
}
ULIB_SERIALIZE_OBJECT(A, Object) { ar &AR(numa); }
struct B : virtual Object {
uLibTypeMacro(B,Object)
B() : numb(5552369) {}
int numb;
uLibTypeMacro(B, Object) B() : numb(5552369) {}
int numb;
};
ULIB_SERIALIZABLE_OBJECT(B)
ULIB_SERIALIZE_OBJECT(B,Object) { ar & AR(numb); }
ULIB_SERIALIZE_OBJECT(B, Object) { ar &AR(numb); }
struct C : B {
uLibTypeMacro(C,B)
C() : numc(5552370) {}
int numc;
uLibTypeMacro(C, B) C() : numc(5552370) {}
int numc;
};
ULIB_SERIALIZABLE_OBJECT(C)
ULIB_SERIALIZE_OBJECT(C,B) { ar & AR(numc); }
ULIB_SERIALIZE_OBJECT(C, B) { ar &AR(numc); }
struct D : A,B {
uLibTypeMacro(D,A,B)
struct D : A, B {
uLibTypeMacro(D, A, B)
D() : numd(5552371) {}
int numd;
D()
: numd(5552371) {}
int numd;
};
ULIB_SERIALIZABLE_OBJECT(D)
ULIB_SERIALIZE_OBJECT(D,A,B) { ar & AR(numd); }
ULIB_SERIALIZE_OBJECT(D, A, B) { ar &AR(numd); }
int main() {
A o;
main() {
A o; o.init_properties();
Archive::xml_oarchive(std::cout) << NVP(o);
Archive::xml_oarchive(std::cout) << NVP(o);
}

View File

@@ -23,20 +23,16 @@
//////////////////////////////////////////////////////////////////////////////*/
#include <iostream>
#include <fstream>
#include <iostream>
#include "Core/Object.h"
#include "Core/Archives.h"
#include "Core/Object.h"
#include "testing-prototype.h"
using namespace uLib;
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
@@ -45,63 +41,51 @@ using namespace uLib;
struct V3f {
float x,y,z;
V3f()
{ x = y = z =0; }
float x, y, z;
V3f() { x = y = z = 0; }
V3f(float x, float y, float z) :
x(x), y(y), z(z) {}
V3f(float x, float y, float z) : x(x), y(y), z(z) {}
template <class Archive>
void serialize (Archive &ar,unsigned int v) {
ar
& "<" & NVP(x) & NVP(y) & NVP(z) & ">";
}
template <class Archive> void serialize(Archive &ar, unsigned int v) {
ar & "<" & NVP(x) & NVP(y) & NVP(z) & ">";
}
};
ULIB_CLASS_EXPORT_KEY(V3f);
ULIB_CLASS_EXPORT_IMPLEMENT(V3f);
inline std::ostream &
operator <<(std::ostream &o, const V3f &v) {
Archive::hrt_oarchive(o) << v;
return o;
inline std::ostream &operator<<(std::ostream &o, const V3f &v) {
Archive::hrt_oarchive(o) << v;
return o;
}
inline std::istream &
operator >>(std::istream &is, V3f &v) {
Archive::hrt_iarchive(is) >> v;
return is;
inline std::istream &operator>>(std::istream &is, V3f &v) {
Archive::hrt_iarchive(is) >> v;
return is;
}
int test_V3f() {
// testing human readble archive with simple serializable structure //
// testing human readble archive with simple serializable structure //
V3f v1(1,2,3),v2,v3,v4;
std::cout << "v --> " << v1 << "\n";
V3f v1(1, 2, 3), v2, v3, v4;
std::cout << "v --> " << v1 << "\n";
std::stringstream ss; ss << v1;
std::cout << "ss.v --> " << ss.str() << "\n";
std::stringstream ss;
ss << v1;
std::cout << "ss.v --> " << ss.str() << "\n";
Archive::hrt_iarchive ar(ss); ar >> v2;
std::cout << "v2 --> " << v2 << "\n";
Archive::hrt_iarchive ar(ss);
ar >> v2;
std::cout << "v2 --> " << v2 << "\n";
std::stringstream("<2 3 4>") >> v3;
std::cout << "v3 --> " << v3 << "\n";
std::stringstream("<2 3 4>") >> v3;
std::cout << "v3 --> " << v3 << "\n";
// std::cout << "insert V3f string to parse: "; std::cin >> v4;
// std::cout << "v4 --> " << v4 << "\n";
return (1);
// std::cout << "insert V3f string to parse: "; std::cin >> v4;
// std::cout << "v4 --> " << v4 << "\n";
return (1);
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
@@ -109,104 +93,72 @@ int test_V3f() {
// OBJECT SERIALIZATION //
class A : public virtual Object {
uLibTypeMacro(A,Object)
ULIB_SERIALIZE_ACCESS
public:
A() : m_a(5552368) {}
uLibTypeMacro(A, Object) ULIB_SERIALIZE_ACCESS public : A() : m_a(5552368) {}
properties() {
std::string p_a;
};
void init_properties();
std::string p_a;
uLibRefMacro(a, int);
uLibRefMacro (a,int);
private:
int m_a;
int m_a;
};
void A::init_properties() {
$_init();
$$.p_a = "A property string";
}
void A::init_properties() { p_a = "A property string"; }
ULIB_SERIALIZABLE_OBJECT(A)
ULIB_SERIALIZE_OBJECT(A,Object) {
ar
& "Object A : "
& "--> m_a = " & AR(m_a)
& "\n";
ULIB_SERIALIZE_OBJECT(A, Object) {
ar & "Object A : " & "--> m_a = " & AR(m_a) & "\n" & "Object A properties: " &
"---> p_a = " & AR(p_a) & "\n";
}
ULIB_SERIALIZE_OBJECT_PROPS(A) {
ar
& "Object A properties: "
& "---> p_a = " & AR(p_a) & "\n";
}
int testing_xml_class() {
A a; a.init_properties();
A a;
a.init_properties();
{
std::ofstream file("test.xml");
Archive::xml_oarchive(file) << NVP(a);
}
a.a() = 0;
a.$$.p_a = "zero string";
{
std::ifstream file("test.xml");
Archive::xml_iarchive(file) >> NVP(a);
}
{
std::ofstream file("test.xml");
Archive::xml_oarchive(file) << NVP(a);
}
a.a() = 0;
a.p_a = "zero string";
{
std::ifstream file("test.xml");
Archive::xml_iarchive(file) >> NVP(a);
}
Archive::xml_oarchive(std::cout) << NVP(a);
return ( a.a() == 5552368 && a.$$.p_a == "A property string" );
Archive::xml_oarchive(std::cout) << NVP(a);
return (a.a() == 5552368 && a.p_a == "A property string");
}
int testing_hrt_class() {
A a; a.init_properties();
A a;
a.init_properties();
{
std::ofstream file("test.xml");
Archive::hrt_oarchive(file) << NVP(a);
}
a.a() = 0;
a.$$.p_a = "zero string";
{
// ERRORE FIX !
// std::ifstream file("test.xml");
// Archive::hrt_iarchive(file) >> NVP(a);
}
{
std::ofstream file("test.xml");
Archive::hrt_oarchive(file) << NVP(a);
}
a.a() = 0;
a.p_a = "zero string";
{
// ERRORE FIX !
// std::ifstream file("test.xml");
// Archive::hrt_iarchive(file) >> NVP(a);
}
Archive::hrt_oarchive(std::cout) << NVP(a);
return ( a.a() == 5552368 && a.$$.p_a == "A property string" );
Archive::hrt_oarchive(std::cout) << NVP(a);
return (a.a() == 5552368 && a.p_a == "A property string");
}
int main() {
BEGIN_TESTING(Serialize Test);
BEGIN_TESTING(Serialize Test);
TEST1( test_V3f() );
TEST1( testing_xml_class() );
// testing_hrt_class(); ///// << ERRORE in HRT with properties
TEST1(test_V3f());
TEST1(testing_xml_class());
// testing_hrt_class(); ///// << ERRORE in HRT with properties
END_TESTING;
END_TESTING;
}

View File

@@ -23,90 +23,73 @@
//////////////////////////////////////////////////////////////////////////////*/
#include <iostream>
#include "testing-prototype.h"
#include <Core/StaticInterface.h>
namespace uLib {
//// INTERFACE TO COMPLEX CLASS /////
namespace Interface {
struct Test {
MAKE_TRAITS
template<class Self> void check_structural() {
uLibCheckFunction(Self,test,bool,int,float);
uLibCheckMember(Self,testmemb,int);
}
MAKE_TRAITS
template <class Self> void check_structural() {
uLibCheckFunction(Self, test, bool, int, float);
uLibCheckMember(Self, testmemb, int);
}
};
}
} // namespace Interface
struct Test {
bool test(int i, float f){}
int testmemb;
bool test(int i, float f) { return true; }
int testmemb;
};
//// INTERFAC TO SIMPLE CLASS ///////////
namespace Interface {
struct Simple {
MAKE_TRAITS
template<class Self> void check_structural() {
uLibCheckMember(Self,memb1,int);
uLibCheckMember(Self,memb2,float);
}
MAKE_TRAITS
template <class Self> void check_structural() {
uLibCheckMember(Self, memb1, int);
uLibCheckMember(Self, memb2, float);
}
};
}
} // namespace Interface
struct Simple {
int memb1;
float memb2;
int memb1;
float memb2;
};
/////////////////////////
template <class T>
class UseTest {
template <class T> class UseTest {
public:
UseTest() {
Interface::IsA<T,Interface::Test>();
T t;
int i; float f;
t.test(i,f);
}
UseTest() {
Interface::IsA<T, Interface::Test>();
T t;
int i;
float f;
t.test(i, f);
}
};
template <class T>
class UseSimple {
template <class T> class UseSimple {
public:
UseSimple() {
Interface::IsA<T,Interface::Simple>();
}
UseSimple() { Interface::IsA<T, Interface::Simple>(); }
};
} // namespace uLib
int main() {
BEGIN_TESTING(Static Interface);
uLib::UseTest<uLib::Test> u;
uLib::UseSimple<uLib::Simple> s;
END_TESTING;
}
int main()
{
BEGIN_TESTING(Static Interface);
uLib::UseTest<uLib::Test> u;
uLib::UseSimple<uLib::Simple> s;
END_TESTING;
}