[uLib geometry]

- adds some to Programmable accessors
- Static interface test
- Mpl sequence
This commit is contained in:
Andrea Rigoni
2014-12-19 17:37:44 +00:00
parent d3ac2b9e86
commit 39ee7e4a94
17 changed files with 1379 additions and 384 deletions

View File

@@ -6,11 +6,14 @@
#include "Core/Mpl.h"
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// COMPOUND DETAIL //
namespace uLib {
namespace detail {
template < class _Seq >
struct ClassCompound : ULIB_MPL_INHERIT_SEQ(_Seq) {
typedef _Seq Seq;
@@ -27,7 +30,10 @@ struct ClassCompound : ULIB_MPL_INHERIT_SEQ(_Seq) {
template < class T >
void copy(const T &t, const boost::true_type&) const {
// this must be defined not throwing //
static_cast<T &>(*m_dst) = t;
// TODO: constness should removed to use swap ... (think!)
// std::swap(static_cast<T &>(*m_dst),t);
}
template < class A >
@@ -41,25 +47,42 @@ struct ClassCompound : ULIB_MPL_INHERIT_SEQ(_Seq) {
};
template < class Other >
ClassCompound(const Other &t) {
ClassCompound(const Other &copy) {
typedef typename Other::Seq _seq;
mpl::for_each<_seq>(CopyOp<Other>(&t,this));
mpl::for_each<_seq>(CopyOp<Other>(&copy,this));
}
template < class Other >
const ClassCompound & operator = (const Other &t) {
inline void copy ( const Other &copy ) throw () {
typedef typename Other::Seq _seq;
mpl::for_each<_seq>(CopyOp<Other>(&t,this));
mpl::for_each<_seq>(CopyOp<Other>(&copy,this));
}
template < class Other >
const ClassCompound & operator = (const Other &copy) {
this->copy(copy);
return *this;
}
template < int n, class A >
ClassCompound< typename mpl::replace_el<Seq,A,n>::type >
SetComponent(const A &alg) {
typedef typename mpl::replace_el<Seq,A,n>::type _seq;
ClassCompound< _seq > out = *this;
static_cast< A& >(out) = alg;
return out;
}
};
} // detail
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// COMPOUND SPECIALIZATIONS //
struct Null {};
template < class T0 = Null,
class T1 = Null,
@@ -67,22 +90,38 @@ template < class T0 = Null,
class T3 = Null,
class T4 = Null,
class T5 = Null >
struct ClassCompound {
typedef T0 A0;
typedef T1 A1;
typedef T2 A2;
typedef T3 A3;
typedef T4 A4;
typedef T5 A5;
class ClassCompound : detail::ClassCompound< mpl::vector<> > {
public:
typedef detail::ClassCompound< mpl::vector<> > BaseClass;
//NEVER REACHED //
T0& A0();
T1& A1();
T2& A2();
T3& A3();
T4& A4();
T5& A5();
using BaseClass::operator =;
private:
// NOT ACCESSIBLE because never reached //
ClassCompound() {}
template < class Other >
ClassCompound(const Other &t) : BaseClass(t) {}
};
template < class _A0 >
struct ClassCompound<_A0> : detail::ClassCompound< mpl::vector<_A0> > {
typedef detail::ClassCompound< mpl::vector<_A0> > BaseClass;
typedef _A0 A1;
_A0& A0() { return (_A0&)*this; }
const _A0& A0() const { return (const _A0&)*this; }
ClassCompound() {}
@@ -96,15 +135,18 @@ template < class _A0,
class _A1 >
struct ClassCompound<_A0,_A1> : detail::ClassCompound< mpl::vector<_A0,_A1> > {
typedef detail::ClassCompound< mpl::vector<_A0,_A1> > BaseClass;
typedef _A0 A0;
typedef _A1 A1;
_A0& A0() { return (_A0&)*this; }
_A1& A1() { return (_A1&)*this; }
const _A0& A0() const { return (const _A0&)*this; }
const _A1& A1() const { return (const _A1&)*this; }
ClassCompound() {}
ClassCompound() {}
template < class Other >
ClassCompound(const Other &t) : BaseClass(t) {}
using BaseClass::operator =;
using BaseClass::SetComponent;
};
template < class _A0,
@@ -113,9 +155,12 @@ template < class _A0,
struct ClassCompound<_A0,_A1,_A2> : detail::ClassCompound< mpl::vector<_A0,_A1,_A2> > {
typedef detail::ClassCompound< mpl::vector<_A0,_A1,_A2> > BaseClass;
typedef _A0 A0;
typedef _A1 A1;
typedef _A2 A2;
_A0& A0() { return (_A0&)*this; }
_A1& A1() { return (_A1&)*this; }
_A2& A2() { return (_A2&)*this; }
const _A0& A0() const { return (const _A0&)*this; }
const _A1& A1() const { return (const _A1&)*this; }
const _A2& A2() const { return (const _A2&)*this; }
ClassCompound() {}
@@ -133,10 +178,14 @@ template < class _A0,
struct ClassCompound<_A0,_A1,_A2,_A3> : detail::ClassCompound< mpl::vector<_A0,_A1,_A2,_A3> > {
typedef detail::ClassCompound< mpl::vector<_A0,_A1,_A2,_A3> > BaseClass;
typedef _A0 A0;
typedef _A1 A1;
typedef _A2 A2;
typedef _A3 A3;
_A0& A0() { return (_A0&)*this; }
_A1& A1() { return (_A1&)*this; }
_A2& A2() { return (_A2&)*this; }
_A3& A3() { return (_A3&)*this; }
const _A0& A0() const { return (const _A0&)*this; }
const _A1& A1() const { return (const _A1&)*this; }
const _A2& A2() const { return (const _A2&)*this; }
const _A3& A3() const { return (const _A3&)*this; }
ClassCompound() {}
@@ -154,11 +203,16 @@ template < class _A0,
struct ClassCompound<_A0,_A1,_A2,_A3,_A4> : detail::ClassCompound< mpl::vector<_A0,_A1,_A2,_A3,_A4> > {
typedef detail::ClassCompound< mpl::vector<_A0,_A1,_A2,_A3,_A4> > BaseClass;
typedef _A0 A0;
typedef _A1 A1;
typedef _A2 A2;
typedef _A3 A3;
typedef _A4 A4;
_A0& A0() { return (_A0&)*this; }
_A1& A1() { return (_A1&)*this; }
_A2& A2() { return (_A2&)*this; }
_A3& A3() { return (_A3&)*this; }
_A4& A4() { return (_A4&)*this; }
const _A0& A0() const { return (const _A0&)*this; }
const _A1& A1() const { return (const _A1&)*this; }
const _A2& A2() const { return (const _A2&)*this; }
const _A3& A3() const { return (const _A3&)*this; }
const _A4& A4() const { return (const _A4&)*this; }
ClassCompound() {}

View File

@@ -15,6 +15,122 @@
namespace uLib {
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// RUNTIME CLASS FACTORY not jet usable... classes under development !
template <
class BaseType,
template <class T1, class T2> class DerivedType,
typename S1,
typename S2
>
class Factory2 {
typedef Factory2 ThisClass;
typedef void*(ThisClass::* newClassFn)(void *,void *);
typedef std::vector<newClassFn> newClassFnVector;
typedef mpl::combine_view< mpl::vector<S1,S2> > AlgView;
template <class U, class V>
void * newClass(void *ob1, void *ob2 ) {
DerivedType<U,V> *out = new DerivedType<U,V>;
if(ob1) static_cast<U&>(*out) = *static_cast<U*>(ob1);
if(ob2) static_cast<V&>(*out) = *static_cast<V*>(ob2);
return out;
}
template < typename U, typename V >
void addType() { m_map.push_back(&ThisClass::newClass< U,V >); }
struct AddTypeSeqOp {
AddTypeSeqOp( Factory2 *_p) : m_parent(_p) {}
template < typename Seq >
void operator()(Seq) {
m_parent->addType<
typename mpl::at<Seq, mpl::int_<0> >::type,
typename mpl::at<Seq, mpl::int_<1> >::type
> ();
}
Factory2 *m_parent;
};
BaseType * create() {
typename newClassFnVector::iterator itr = m_map.begin() + m_id0 + m_size1 * m_id1;
return (BaseType *)(this->*(*itr))(m_algs[0], m_algs[1]);
}
public:
Factory2() :
m_id0(0), m_id1(0)
{
mpl::for_each< AlgView >(AddTypeSeqOp(this));
m_algs[0] = NULL;
m_algs[1] = NULL;
m_base = create();
}
BaseType * operator -> () const { return m_base; }
template < typename T >
static inline int FindS1() {
typedef typename mpl::find<S1,T>::type iter;
return iter::pos::value;
}
template < typename T >
static inline int FindS2() {
typedef typename mpl::find<S2,T>::type iter;
return iter::pos::value;
}
template < class A >
void setA0 (A* alg) {
m_algs[0] = alg;
m_id0 = FindS1<A>();
delete m_base;
m_base = create();
}
template < class A >
void setA1 (A* alg) {
m_algs[1] = alg;
m_id1 = FindS2<A>();
delete m_base;
m_base = create();
}
private:
newClassFnVector m_map;
int m_id0, m_id1;
void * m_algs[2];
BaseType *m_base;
static const int m_size1 = mpl::size<S1>::type::value;
static const int m_size2 = mpl::size<S2>::type::value;
};
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// generator //
@@ -196,12 +312,6 @@ class RegisteredClassFactory2 {
typedef mpl::combine_view< mpl::vector<S1,S2> > AlgView;
// template < typename _T, class _Seq >
// static inline int find() {
// typedef typename mpl::find<_Seq,_T>::type iter;
// return iter::pos::value;
// }
public:
RegisteredClassFactory2() {

View File

@@ -46,6 +46,10 @@
#include <boost/mpl/transform_view.hpp>
#include <boost/mpl/filter_view.hpp>
#include <boost/mpl/replace.hpp>
#include <boost/mpl/erase.hpp>
#include <boost/mpl/insert.hpp>
#include <boost/mpl/list.hpp>
#include <boost/mpl/map.hpp>
#include <boost/mpl/string.hpp>
@@ -127,11 +131,10 @@ struct inherit_nofold {
template< class T>
struct type {
struct type {};
};
template <const char *N, class T>
struct nvp {
@@ -142,6 +145,20 @@ struct nvp {
template < class Seq, class A, int N >
class replace_el {
template < class _Seq, int _n >
struct pos {
typedef typename mpl::begin<_Seq>::type begin;
typedef typename mpl::advance<begin, mpl::int_<_n> >::type type;
};
typedef typename mpl::erase<Seq, typename pos<Seq,N>::type >::type s1;
typedef typename mpl::insert<s1, typename pos<s1,N>::type , A>::type result;
public:
typedef result type;
};
} // mpl

View File

@@ -1,6 +1,9 @@
#ifndef U_CORE_PROGRAMMABLEACCESSOR_H
#define U_CORE_PROGRAMMABLEACCESSOR_H
#include <boost/type_traits.hpp>
#include <boost/type_traits/is_pointer.hpp>
#include <Core/Macros.h>
#include <Core/Types.h>
#include <Core/SmartPointer.h>
@@ -17,25 +20,15 @@ namespace uLib {
namespace detail {
template <typename T>
struct is_iterator {
template <typename U>
static char test(typename U::iterator_category* x);
template <typename U>
static long test(U* x);
class any_c : public boost::any {
typedef boost::any any;
public:
any_c() : any() {}
template<typename ValueType>
any_c(const ValueType & value) : any(value) {}
any_c(const any & other) : any(other) {}
// FIX !! //
// this is needed to tait static_cast using any_cast function //
template <typename _TT>
operator _TT () const { return boost::any_cast<_TT>(*this); }
static const bool value = sizeof(test<T>(nullptr)) == 1;
};
@@ -48,20 +41,60 @@ public:
virtual D Get(void *) const = 0;
virtual void Set(void *,const D) const = 0;
template <typename T>
T Get(void *ob) const {
return static_cast<T>(this->Get(ob));
}
// template <typename T>
// T Get(void *ob) const {
// return static_cast<T>(this->Get(ob));
// }
template <typename T>
void Set(void *ob, const T data) const {
this->Set(ob,static_cast<D>(data));
}
// template <typename T>
// void Set(void *ob, const T data) const {
// this->Set(ob,static_cast<D>(data));
// }
virtual ~ProgrammableAccessor_Base() {}
};
template<typename D, typename R, class T1>
class functor_by_static_acc : public ProgrammableAccessor_Base<D>
{
typedef R(*GeT)(const T1 *);
typedef void(*SeT)(T1 *,R);
public:
explicit functor_by_static_acc(GeT _get, SeT _set = NULL) :
GetPtr(_get), SetPtr(_set) {}
D Get(void * ptr) const
{ return static_cast<D>((*GetPtr)(reinterpret_cast<const T1 *>(ptr))); }
void Set(void * ptr, const D data) const
{ if (SetPtr) (*SetPtr)(reinterpret_cast<T1 *>(ptr),static_cast<const R>(data)); }
private:
GeT GetPtr;
SeT SetPtr;
};
template<typename D, typename R, class T1>
class functor_by_static_acc_ref : public ProgrammableAccessor_Base<D>
{
typedef R(*GeT)(const T1 &);
typedef void(*SeT)(T1 &,R);
public:
explicit functor_by_static_acc_ref(GeT _get, SeT _set = NULL) :
GetPtr(_get), SetPtr(_set) {}
D Get(void * ptr) const
{ return static_cast<D>((*GetPtr)(reinterpret_cast<const T1 &>(ptr))); }
void Set(void * ptr, const D data) const
{ if (SetPtr) (*SetPtr)(reinterpret_cast<T1 &>(ptr),static_cast<const R>(data)); }
private:
GeT GetPtr;
SeT SetPtr;
};
template<typename D, typename R, typename T>
class functor_by_ref : public ProgrammableAccessor_Base<D>
{
@@ -83,8 +116,10 @@ class functor_by_mfptr_cc : public ProgrammableAccessor_Base<D>
public:
explicit functor_by_mfptr_cc( GeT _get, SeT _set ) :
GetPtr(_get), SetPtr(_set) {}
D Get(void * ptr) const
{ return static_cast<D>((reinterpret_cast<T *>(ptr)->*GetPtr)()); }
void Set(void * ptr, const D data) const
{ if (SetPtr) (reinterpret_cast<T *>(ptr)->*SetPtr)(static_cast<const R>(data)); }
@@ -146,22 +181,24 @@ template <typename D >
class ProgrammableAccessor : public Named {
public:
struct Wrapper {
Wrapper(const ProgrammableAccessor<D> *ac, void *ob) :
m_access(ac), m_object(ob)
{ assert(ob != NULL); }
// struct Wrapper {
// Wrapper(const ProgrammableAccessor<D> *ac, void *ob) :
// m_access(ac), m_object(ob)
// { assert(ob != NULL); }
template <typename T>
inline T Get() const { return m_access->Get<T>(m_object); }
// template <typename T>
// inline T Get() const { return static_cast<T>(m_access->Get(m_object)); }
template <typename T>
inline void Set(const T data) const { return m_access->Set<T>(m_object,data); }
// template <typename T>
// inline void Set(const T data) const { return m_access->Set(m_object,static_cast<T>(data)); }
void *m_object;
const ProgrammableAccessor<D> *m_access;
};
// void *m_object;
// const ProgrammableAccessor<D> *m_access;
// };
ProgrammableAccessor() : Named("no access defined") {}
ProgrammableAccessor() : Named("") {}
ProgrammableAccessor(const char *name) : Named(name) {}
template < typename F >
ProgrammableAccessor(F f) : Named(f)
@@ -173,52 +210,84 @@ public:
// ----- move to factory //
template <typename R, typename T1>
inline void SetAccessFunctions(R(*_pg)(const T1 *), void(*_ps)(T1*,R) = NULL) {
m_base = SmartPointer< detail::ProgrammableAccessor_Base<D> >(new detail::functor_by_static_acc<D,R,T1>(_pg,_ps));
}
template <typename R, typename T1>
inline void SetAccessFunctions(R(*_pg)(const T1&), void(*_ps)(T1&,R) = NULL) {
m_base = SmartPointer< detail::ProgrammableAccessor_Base<D> >(new detail::functor_by_static_acc_ref<D,R,T1>(_pg,_ps));
}
template <typename R, typename T>
inline void SetAccessFunctions(R(T::*_pg)()const, void(T::*_ps)(const R) = NULL)
{
m_base = SmartPointer< detail::ProgrammableAccessor_Base<D> >(new detail::functor_by_mfptr_cc<D,R,T>(_pg,_ps));
this->SetName(_pg); // << FIX
}
template <typename R, typename T>
inline void SetAccessFunctions(R(T::*_pg)(), void(T::*_ps)(R) = NULL) {
m_base = SmartPointer< detail::ProgrammableAccessor_Base<D> >(new detail::functor_by_mfptr_vv<D,R,T>(_pg,_ps));
this->SetName(_pg); // << FIX
}
template <typename R, typename T>
inline void SetAccessFunctions(R&(T::*_pf)()) {
m_base = SmartPointer< detail::ProgrammableAccessor_Base<D> >(new detail::functor_by_ref<D,R,T>(_pf));
this->SetName(_pf);
}
template <typename R, typename T>
inline void SetAccessFunctions(R T::*_pf) {
m_base = SmartPointer< detail::ProgrammableAccessor_Base<D> >(new detail::functor_by_member<D,R,T>(_pf));
this->SetName(_pf);
}
// ------ //
const Wrapper operator() (void *ob) const { return Wrapper(this,ob); }
// const Wrapper operator() (void *ob) const { return Wrapper(this,ob); }
inline D Get(void *ob) const { return m_base->Get(ob); }
inline void Set(void *ob, const D data) const { m_base->Set(ob,data); }
template <typename T>
inline T Get(void *ob) const { return m_base->Get<T>(ob); }
inline T Get(void *ob) const
{ return static_cast<T>(m_base->Get(ob)); }
template <typename T>
inline void Set(void *ob, const T data) const { return m_base->Set<T>(ob,data); }
inline void Set(void *ob, const T data) const
{ return m_base->Set(ob,static_cast<T>(data)); }
template <typename T>
inline D Get(const T &ob,
typename boost::disable_if< detail::is_iterator<T> >::type *d1 = 0,
typename boost::disable_if< boost::is_pointer<T> >::type *d2 = 0 ) const
{ return m_base->Get((void*)(&ob)); } // FIX << add "void * const" to Getters
template <typename T>
inline void Set(T &ob, const D data,
typename boost::disable_if< detail::is_iterator<T> >::type *d1 = 0,
typename boost::disable_if< boost::is_pointer<T> >::type *d2 = 0) const
{ return m_base->Set(&ob,data); }
template <typename It>
inline D Get(const It &it,
typename boost::enable_if< detail::is_iterator<It> >::type *d1 = 0,
typename boost::disable_if< boost::is_pointer<It> >::type *d2 = 0) const
{ return m_base->Get(it.base()); }
template <typename It>
inline void Set(const It &it, const D data,
typename boost::enable_if< detail::is_iterator<It> >::type *d1 = 0,
typename boost::disable_if< boost::is_pointer<It> >::type *d2 = 0) const
{ return m_base->Set(it.base(),data); }
private:
SmartPointer< detail::ProgrammableAccessor_Base<D> > m_base;
};
typedef ProgrammableAccessor<detail::any_c> ProgrammableAccessorAny;
} // uLib

View File

@@ -24,10 +24,14 @@
//////////////////////////////////////////////////////////////////////////////*/
#ifndef U_CORE_STATICINTERFACE_H
#define U_CORE_STATICINTERFACE_H
#include "boost/concept_check.hpp"
#include "boost/type_traits/is_base_of.hpp"
namespace uLib {
@@ -85,12 +89,54 @@ static inline void IsA(T &t) {
template <class T, class SI>
struct StaticIsA {
StaticIsA() {
void (SI::*x)() = &SI::template check_structural<T>;
static void (SI::*x)() = &SI::template check_structural<T>;
(void) x;
}
};
} // Interface
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// BOOST CONCEPT CHECK FOR INTERFACES //
// fix error dump for virtual interfaces //
template < class I, class T >
struct IsInterfaceOf {
typedef IsInterfaceOf<I,T> ThisClass;
template <class Model>
struct usage_requirements
{ ~usage_requirements() { ((Model*)0)->~Model(); } };
BOOST_CONCEPT_ASSERT((boost::concepts::usage_requirements<ThisClass>));
void test( const boost::false_type &) {
I interface = target;
(void) interface;
}
void test( const boost::true_type &) {
I * interface = new T;
(void) interface;
}
~IsInterfaceOf() {
this->test( boost::is_base_of<I,T>() );
}
T target;
};
} // uLib
#define ULIB_INTERFACE_ASSERT(interface, type) \
BOOST_CONCEPT_ASSERT(( uLib::IsInterfaceOf<interface,type> ))
#endif // STATICINTERFACE_H

View File

@@ -228,6 +228,79 @@ struct TypeIntrospection {
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// CONCEPTS //
class NonCopyable
{
NonCopyable (NonCopyable const &); // private copy constructor
NonCopyable & operator = (NonCopyable const &); // private assignment operator
};
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// TYPES WRAPPERS //
template < typename T >
struct WrapType { typedef T type; };
template < typename T >
class WrapMember {
public:
typedef T type;
WrapMember() {}
WrapMember(const T &t) : _wrapped_member(t) {}
operator T () { return _wrapped_member; }
operator const T () const { return _wrapped_member; }
operator T& () { return _wrapped_member; }
operator const T& () const { return _wrapped_member; }
private:
T _wrapped_member;
};
template < typename T, T _value >
struct WrapValue { static const T value = _value; };
typedef WrapValue<bool,true> StaticTrue;
typedef WrapValue<bool,false> StaticFalse;
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// RAII //
template <class T>
class AutoDelete : NonCopyable
{
public:
AutoDelete (T * p = 0) : m_ptr(p) {}
~AutoDelete () throw() { delete m_ptr; }
private:
T *m_ptr;
};
template < class Lock >
class ScopedLock : NonCopyable
{
public:
ScopedLock (Lock & l) : m_lock(l) { m_lock.acquire(); }
~ScopedLock () throw () { m_lock.release(); }
private:
Lock& m_lock;
};
// SISTEMARE //

View File

@@ -23,8 +23,10 @@ set( TESTS
OptionsTest
ProgrammableAccessorTest
ClassFactoryTest
ClassFactoryRuntimeTest
MplSequenceCombinerTest
ClassCompoundTest
MplSequenceReplaceElTest
)
set(LIBRARIES

View File

@@ -28,6 +28,12 @@
#include "Core/Vector.h"
#include "Core/ClassCompound.h"
#include "Core/StaticInterface.h"
#include "Core/Mpl.h"
#include "testing-prototype.h"
using namespace uLib;
@@ -69,8 +75,26 @@ private:
class VoxCountInterface {
// int (* p_Count)(void * const);
// template <class T> static int S_Count(void * const ob) { return static_cast<T*>(ob)->Count(); }
void * const m_ob;
public:
template < class T >
VoxCountInterface( T &t ) :
m_ob(&t)/*,
p_Count(&S_Count<T>)*/
{}
// int Count() const { return (*p_Count)(m_ob); }
};
class VoxCount {
public:
template < class T >
int Count(const Vector<T> &ref ) const {
return ref.size();
@@ -104,9 +128,14 @@ public:
virtual ~VoxelVectorBase() {}
};
template < class T >
void copy(T *src, T *dst) { }
void copy(VoxelVectorBase *src, VoxelVectorBase *dst) {
for(int i=0; i<src->Size(); ++i) {
dst->Set(i,src->Get(i));
@@ -114,52 +143,83 @@ void copy(VoxelVectorBase *src, VoxelVectorBase *dst) {
}
template < class VoxType,
template < class Container,
class CounterType >
class VoxelVector :
public VoxelVectorBase,
public ClassCompound< VoxType, CounterType >
public ClassCompound< Container, CounterType>
{
typedef ClassCompound< VoxType, CounterType > Compound;
typedef ClassCompound< Container, CounterType> Compound;
public:
VoxelVector() {}
template < class Other >
VoxelVector(const Other &t) : Compound(t) {
// assumes that Other is a voxelvector //
for(int i=0; i<t.Size(); ++i) {
this->Set(i, t.Get(i));
}
}
VoxelVector(const Other &copy) : Compound(copy) {}
template < class Other >
VoxelVector & operator = (const Other &t) {
for(int i=0; i<t.Size(); ++i) {
this->Set(i, t.Get(i));
}
(Compound &)(*this) = t;
return *this;
}
float Get(int id) const { return this->at(id).Get(); }
using Compound::operator =;
float Get(int id) const { return m_data[id].Get(); }
void Set(int id, float data) {
if(id >= Size()) m_data.resize(id+1);
m_data[id].Set(data);
if(id >= Size()) this->resize(id+1);
this->at(id).Set(data);
}
int Size() const { return m_data.size(); }
int Size() const { return this->size(); }
int Count() const {
return CounterType::Count(m_data);
return CounterType::Count( this->A0() );
}
private:
friend class VoxelVectorFactory;
Vector<VoxType> m_data;
// friend class VoxelVectorFactory;
};
template < class ContainerInterface,
class CounterInterface >
class VoxelVectorFactory
{
public:
template < class T0, class T1 >
static VoxelVector<T0,T1> * create( const T0 &t0, const T1 &t1) {
VoxelVector<T0,T1> *out = new VoxelVector<T0,T1>;
ULIB_INTERFACE_ASSERT(VoxCountInterface,T1);
out->A0() = t0;
out->A1() = t1;
return out;
}
// template < class H0, class A, int n >
// static void Set(const H0 &hold, const A &alg) {
// }
// template < class A, int n >
// typename mpl::replace_el<Seq,A,n>::type
// SetComponent(const A &alg) {
// typedef typename mpl::replace_el<Seq,A,n>::type _seq;
// result_type out = *this;
// static_cast< A& >(out) = alg;
// return out;
// }
};
} // Test
@@ -169,33 +229,97 @@ using namespace Test;
int main() {
VoxelVector< VoxelMean, VoxCountOver > img;
VoxelVector< Vector<VoxelMean>, VoxCountOver > img;
img.Set(0,555);
img.Set(1,23);
img.Set(1,25);
img.Set(2,68);
img.A1::m_threshold = 50;
{
// these are equivalent access methods //
img.A1().m_threshold = 50;
img.VoxCountOver::m_threshold = 50;
VoxCountOver counter;
counter.m_threshold = 50;
img.A1() = counter;
// ----------------------------------- //
}
std::cout << "-> ";
for(int i=0; i<3; ++i) {
std::cout << img.Get(i) << " ";
}
std::cout << " count threshold: " << img.A1().m_threshold << " ";
std::cout << " count: " << img.Count() << "\n";
VoxelVector< VoxelVal, VoxCountOver > img2 = img;
VoxelVector< Vector<VoxelVal>, VoxCountOver > img2;
img2 = img;
// voxel is changed so objects must be copied //
foreach (VoxelMean &el, img) {
VoxelVal v; v.Set(el.Get());
img2.push_back(v);
}
// manual copy of content //
img2.Set(1,0);
std::cout << "-> ";
for(int i=0; i<3; ++i) {
std::cout << img2.Get(i) << " ";
}
std::cout << " count threshold: " << img2.A1::m_threshold << " ";
std::cout << " count threshold: " << img2.A1().m_threshold << " ";
std::cout << " count: " << img2.Count() << "\n";
VoxelVector< Vector<VoxelVal>, VoxCount > img3 = img2;
std::cout << "-> ";
for(int i=0; i<3; ++i) {
std::cout << img3.Get(i) << " ";
}
std::cout << " count: " << img3.Count() << "\n";
VoxelVector< Vector<VoxelVal>, VoxCount > img4;
img4 = img3.SetComponent<1>(VoxCountOver());
std::cout << "-> ";
for(int i=0; i<3; ++i) {
std::cout << img4.Get(i) << " ";
}
std::cout << " count: " << img4.Count() << "\n";
{
// Voxel Vector Factory //
VoxelVectorFactory< Vector<VoxelVal>, VoxCount > factory;
Vector<VoxelVal> vector;
VoxCount counter;
VoxelVectorBase * base = factory.create(vector,counter);
base->Set(0,123);
base->Set(1,234);
base->Set(2,345);
std::cout << "-> ";
for(int i=0; i<3; ++i) {
std::cout << base->Get(i) << " ";
}
std::cout << " count: " << base->Count() << "\n";
}
}

View File

@@ -0,0 +1,246 @@
/*//////////////////////////////////////////////////////////////////////////////
// CMT Cosmic Muon Tomography project //////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova
All rights reserved
Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it >
------------------------------------------------------------------
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3.0 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library.
//////////////////////////////////////////////////////////////////////////////*/
#include <iostream>
#include "Core/MplSequenceCombiner.h"
#include "Core/ClassCompound.h"
#include "Core/ClassFactory.h"
#include "Core/Serializable.h"
#include "testing-prototype.h"
using namespace uLib;
////////////////////////////////////////////////////////////////////////////////
// WORKING EXAMPLE //
namespace Test {
template <
class BaseType,
template <class T1, class T2> class DerivedType,
typename S1,
typename S2
>
class Factory2 {
typedef Factory2 ThisClass;
typedef void*(ThisClass::* newClassFn)(void *,void *);
typedef std::vector<newClassFn> newClassFnVector;
typedef mpl::combine_view< mpl::vector<S1,S2> > AlgView;
template <class U, class V>
void * newClass(void *ob1, void *ob2 ) {
DerivedType<U,V> *out = new DerivedType<U,V>;
if(ob1) static_cast<U&>(*out) = *static_cast<U*>(ob1);
if(ob2) static_cast<V&>(*out) = *static_cast<V*>(ob2);
return out;
}
template < typename U, typename V >
void addType() { m_map.push_back(&ThisClass::newClass< U,V >); }
struct AddTypeSeqOp {
AddTypeSeqOp( Factory2 *_p) : m_parent(_p) {}
template < typename Seq >
void operator()(Seq) {
m_parent->addType<
typename mpl::at<Seq, mpl::int_<0> >::type,
typename mpl::at<Seq, mpl::int_<1> >::type
> ();
}
Factory2 *m_parent;
};
BaseType * create() {
typename newClassFnVector::iterator itr = m_map.begin() + m_id0 + m_size1 * m_id1;
return (BaseType *)(this->*(*itr))(m_algs[0], m_algs[1]);
}
public:
Factory2() :
m_id0(0), m_id1(0)
{
mpl::for_each< AlgView >(AddTypeSeqOp(this));
m_algs[0] = NULL;
m_algs[1] = NULL;
m_base = create();
}
BaseType * operator -> () const { return m_base; }
template < typename T >
static inline int FindS1() {
typedef typename mpl::find<S1,T>::type iter;
return iter::pos::value;
}
template < typename T >
static inline int FindS2() {
typedef typename mpl::find<S2,T>::type iter;
return iter::pos::value;
}
template < class A >
void setA0 (A* alg) {
m_algs[0] = alg;
m_id0 = FindS1<A>();
delete m_base;
m_base = create();
}
template < class A >
void setA1 (A* alg) {
m_algs[1] = alg;
m_id1 = FindS2<A>();
delete m_base;
m_base = create();
}
private:
newClassFnVector m_map;
int m_id0, m_id1;
void * m_algs[2];
BaseType *m_base;
static const int m_size1 = mpl::size<S1>::type::value;
static const int m_size2 = mpl::size<S2>::type::value;
};
} // Test
struct B1 {
B1() : m_b1(1) {}
void Print() { std::cout << m_b1; }
int m_b1;
};
struct B2 {
B2() : m_b2(2) {}
void Print() { std::cout << m_b2; }
int m_b2;
};
struct B3 {
B3() : m_b3(3) {}
void Print() { std::cout << m_b3; }
int m_b3;
};
struct B3b {
B3b() : m_b3(30) {}
void Print() { std::cout << m_b3; }
int m_b3; // learn to handle ambiguity ..
};
struct HB {
virtual ~HB() {}
virtual void Print() = 0;
};
template <
class A0,
class A1
>
struct H : HB, ClassCompound<A0,A1> {
typedef ClassCompound<A0,A1> Compound;
H() {}
template < class Other >
H(const Other &t) : Compound(t) {}
using Compound::operator =;
template < class T >
H<T,A1> SetA0(const T &t) {
H<T,A1> out(*this);
(T&)out = t;
return out;
}
void Print() {
std::cout << "this is a holder of type: " << typeid(this).name() << "\n";
std::cout << "-> ";
A0::Print();
std::cout << " ";
A1::Print();
std::cout << "\n";
}
};
typedef mpl::vector< B1, B2 > seq1;
typedef mpl::vector< B3, B3b > seq2;
int main() {
Test::Factory2< HB, H, seq1, seq2 > f;
B1 b1;
B2 b2;
B3 b3;
f.setA0(&b1);
f.setA1(&b3);
f->Print();
f.setA0(&b2);
f->Print();
}

View File

@@ -28,11 +28,14 @@
//#include "boost/preprocessor.hpp"
//#include "boost/preprocessor/repetition.hpp"
#include "boost/concept_archetype.hpp"
#include "Core/MplSequenceCombiner.h"
#include "Core/ClassCompound.h"
#include "Core/ClassFactory.h"
#include "Core/StaticInterface.h"
#include "Core/Serializable.h"
#include "testing-prototype.h"
@@ -42,204 +45,140 @@ using namespace uLib;
////////////////////////////////////////////////////////////////////////////////
// WORKING EXAMPLE //
// TEST 1 //
/*
* TEST 1
namespace Test {
struct BB {};
class Voxel {
public:
virtual void Set(float) = 0;
virtual float Get() const = 0;
virtual ~Voxel() {}
};
class VoxelMean : public Voxel {
public:
VoxelMean() : m_data(0), m_count(0) {}
void Set(float data) { m_data += data; ++m_count; }
float Get() const { return m_data / m_count; }
private:
float m_data;
int m_count;
};
class VoxelVal : public Voxel {
public:
VoxelVal() : m_data(0) {}
void Set(float data) { m_data = data; }
float Get() const { return m_data; }
private:
float m_data;
};
class VoxCount {
public:
template < class T >
int Count(const Vector<T> &ref ) const {
return ref.size();
}
};
class VoxCountOver {
public:
VoxCountOver() : m_threshold(0) {}
template < class T >
int Count(const Vector<T> &ref ) const {
int count = 0 ;
foreach (const T &el, ref) {
if( el.Get() >= m_threshold ) ++count;
}
return count;
}
float m_threshold;
};
class VoxelVectorBase {
public:
virtual float Get(int) const = 0;
virtual void Set(int,float) = 0;
virtual int Size() const = 0;
virtual int Count() const = 0;
virtual ~VoxelVectorBase() {}
};
template < class T >
void copy(T *src, T *dst) { }
void copy(VoxelVectorBase *src, VoxelVectorBase *dst) {
for(int i=0; i<src->Size(); ++i) {
dst->Set(i,src->Get(i));
}
}
template < class VoxType,
class CounterType >
class VoxelVector : public VoxelVectorBase {
public:
VoxelVector() {} // remove?
VoxelVector( const VoxType *A1, const CounterType *A2 ) {
(void) A1;
SetA2(A2);
}
void * GetA2() { return &m_counter; }
void SetA2(const void *A2) { m_counter = *A2; }
float Get(int id) const { return m_data[id].Get(); }
void Set(int id, float data) {
if(id >= Size()) m_data.resize(id+1);
m_data[id].Set(data);
}
int Size() const { return m_data.size(); }
int Count() const { return m_counter.Count(m_data); }
private:
friend class VoxelVectorFactory;
CounterType m_counter;
Vector<VoxType> m_data;
};
class VoxelVectorFactory {
public:
VoxelVectorFactory() :
m_id1(0), m_id2(0)
{
m_base = m_factory.Create(0,0);
}
~VoxelVectorFactory() {
delete m_base;
}
VoxelVectorBase * operator -> () const { return m_base; }
template < typename T >
void SetVoxel() {
int id = m_factory.FindS1<T>();
VoxelVectorBase * newbase = m_factory.Create(id,m_id2);
Test::copy(m_base,newbase); // *newbase = *m_base;
//
delete m_base;
m_base = newbase;
}
template < typename T >
void SetCounter(const T &ref) {
int id = m_factory.FindS2<T>();
VoxelVectorBase * newbase = m_factory.Create(m_id1,id);
Test::copy(m_base,newbase); // *newbase = *m_base;
//
delete m_base;
m_base = newbase;
}
private:
RegisteredClassFactory2< VoxelVectorBase, VoxelVector, mpl::vector<VoxelMean,VoxelVal>, mpl::vector<VoxCount,VoxCountOver> > m_factory;
int m_id1, m_id2;
VoxelVectorBase * m_base;
};
} // Test
struct B1 {
struct B1 : BB {
B1() : m_b1(1) {}
void Print() { std::cout << m_b1; }
int m_b1;
};
struct B2 {
struct B2 : BB {
B2() : m_b2(2) {}
void Print() { std::cout << m_b2; }
int m_b2;
};
struct B3 {
struct B3 : BB {
B3() : m_b3(3) {}
void Print() { std::cout << m_b3; }
int m_b3;
};
struct B3b {
B3b() : m_b3(3) {}
B3b() : m_b3(30) {}
void Print() { std::cout << m_b3; }
int m_b3; // learn to handle ambiguity ..
};
struct HB {
virtual ~HB() {}
virtual void Print() = 0;
};
template <
class A0,
class A1
>
struct H : HB, ClassCompound<A0,A1> {
typedef ClassCompound<A0,A1> Compound;
H() {}
template < class Other >
H(const Other &t) : Compound(t) {}
using Compound::operator =;
using Compound::SetComponent;
void Print() {
std::cout << "this is a holder of type: " << typeid(this).name() << "\n";
std::cout << "-> ";
A0::Print();
std::cout << " ";
A1::Print();
std::cout << "\n";
}
};
struct HFactory {
template < class T0, class T1 >
static H<T0,T1>* create(const T0 &t0, const T1 &t1) {
H<T0,T1> *out = new H<T0,T1>;
out->A0() = t0;
out->A1() = t1;
return out;
}
};
template < class I0, class I1 >
struct CompoundFactory {
template < class T0, class T1 >
static ClassCompound<T0,T1> create(const T0 &t0, const T1 &t1) {
ClassCompound<T0,T1> out;
ULIB_INTERFACE_ASSERT(I0,T0);
ULIB_INTERFACE_ASSERT(I1,T1);
out.A0() = t0;
out.A1() = t1;
return out;
}
};
typedef mpl::vector< B1, B2 > seq1;
typedef mpl::vector< B3, B3b > seq2;
int main() {
ClassCompound< B1, B2 > h1;
ClassCompound< B2, B3, B1 > h2;
B1 b1;
B2 b2;
B3 b3;
B3b b3b;
b1.m_b1 = 111;
b2.m_b2 = 222;
b3.m_b3 = 333;
b3b.m_b3 = 333;
h1.A0::m_b1 = 111;
h1.A1::m_b2 = 222;
H<B1,B2> h12;
h12.A0() = b1;
h2 = h1;
H<B1,B3> h13 = h12.SetComponent<1>(b3);
h13.Print();
{
H<B1,B2> h12 = CompoundFactory<BB,BB>::create(b1,b2);
h12.Print();
}
std::cout << "h1: " << h1.A0::m_b1 << " " << h1.A1::m_b2 << "\n";
std::cout << "h2: " << h2.A0::m_b2 << " " << h2.A1::m_b3 << "\n";
}
} // Test
*/

View File

@@ -0,0 +1,60 @@
/*//////////////////////////////////////////////////////////////////////////////
// CMT Cosmic Muon Tomography project //////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova
All rights reserved
Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it >
------------------------------------------------------------------
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3.0 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library.
//////////////////////////////////////////////////////////////////////////////*/
#include <iostream>
#include <Core/Types.h>
#include <Core/Mpl.h>
#include <boost/type_traits.hpp>
#include "testing-prototype.h"
using namespace uLib;
struct A0 {};
struct A1 {};
struct A2 {};
struct A3 {};
struct A4 {};
struct A5 {};
struct A6 {};
int main() {
BEGIN_TESTING(Core MplSequence Replace element);
typedef mpl::vector<A0,A1,A2,A3,A4> seq;
typedef mpl::replace_el<seq,A6,2>::type new_seq;
PrintTypeId::PrintMplSeq<new_seq>();
// BOOST_MPL_ASSERT(( boost::is_same< new_seq, mpl::vector<A0,A1,A6,A3,A4> > ));
END_TESTING;
}

View File

@@ -11,7 +11,7 @@
#include <iterator>
namespace uLib {
namespace Test {
class TestVoxel {
public:
@@ -23,42 +23,160 @@ public:
};
} // uLib
class Vox {
public:
float value;
int count;
TestVoxel v;
};
struct StaticVoxAcc {
static float Get(const Vox *v) {
return v->value;
}
static void Set(Vox *v, float data) {
v->value = data;
}
};
struct StaticVoxAccRef {
static float Get(const Vox &v) {
return v.value;
}
static void Set(Vox &v, float data) {
v.value = data;
}
};
} // Test
namespace uLib {
} // uLib
using namespace uLib;
template < typename T >
void print_is_iter(const T &t, typename boost::disable_if< detail::is_iterator<T> >::type *dummy = 0 ) {
std::cout << "no";
}
template < typename T >
void print_is_iter(const T &t, typename boost::enable_if< detail::is_iterator<T> >::type *dummy = 0 ) {
std::cout << "yes";
}
int main() {
BEGIN_TESTING(Function Test);
using Test::TestVoxel;
using Test::Vox;
Vector<TestVoxel> v;
v.push_back(TestVoxel());
v.push_back(TestVoxel());
v.push_back(TestVoxel());
v.push_back(TestVoxel());
v.push_back(TestVoxel());
v.push_back(TestVoxel());
v.push_back(TestVoxel());
{ // TEST 1
Vector<TestVoxel> v;
v.push_back(TestVoxel());
v.push_back(TestVoxel());
v.push_back(TestVoxel());
v.push_back(TestVoxel());
v.push_back(TestVoxel());
v.push_back(TestVoxel());
v.push_back(TestVoxel());
v[5].m_data = 5552368.0;
v[5].m_data = 5552368.0;
ProgrammableAccessor<int> f1(&TestVoxel::m_data);
ProgrammableAccessor<char> f2(&TestVoxel::ConstGet);
ProgrammableAccessor<int> f1(&TestVoxel::m_data);
ProgrammableAccessor<char> f2(&TestVoxel::ConstGet);
int i=0;
if(0)
foreach (TestVoxel &el,v) {
f1.Set(&el,i++);
std::cout << " -> " << f2.Get(&el) /*<< " - " << f1(&el).Get()*/ << "\n";
}
int i=0;
foreach (TestVoxel &el,v) {
f1.Set(&el,i++);
std::cout << " -> " << f2.Get(&el) << " - " << f1(&el).Get<float>() << "\n";
TEST1(f1.Get(&v[5]) == 5552368);
}
{ // TEST accessing internal object //
Vox v1,v2;
v1.v.m_data = 111;
v2.v.m_data = 222;
ProgrammableAccessor<TestVoxel> va("test voxel");
va.SetAccessFunctions(&Vox::v);
va.Set(&v2,v1.v);
// TEST1(v2.v == v1.v);
}
{ // TEST Static access
using Test::Vox;
using Test::StaticVoxAcc;
using Test::StaticVoxAccRef;
ProgrammableAccessor<float> va1("static ptr");
va1.SetAccessFunctions(&StaticVoxAcc::Get, &StaticVoxAcc::Set);
ProgrammableAccessor<float> va2("static ref");
va2.SetAccessFunctions(&StaticVoxAcc::Get, &StaticVoxAcc::Set);
Vox v;
v.value = 111;
TEST1 ( va1.Get(v) == 111 );
TEST1 ( va2.Get(v) == 111 );
std::cout << va1.Get(v) << "\n";
std::cout << va2.Get(v) << "\n";
TEST1 ( va1.Get(&v) == 111 );
TEST1 ( va2.Get(&v) == 111 );
std::cout << va1.Get(&v) << "\n";
std::cout << va2.Get(&v) << "\n";
}
{
Vector<Vox>::Iterator it;
Vox v;
std::cout << "is iter? ";
print_is_iter(it);
std::cout << " is iter? ";
print_is_iter(v);
std::cout << "\n";
}
{ // TEST Iterators
Vector<Vox> vc;
vc.push_back(Vox());
vc.push_back(Vox());
vc.push_back(Vox());
vc.push_back(Vox());
vc.push_back(Vox());
ProgrammableAccessor<float> acc("scalar");
acc.SetAccessFunctions(&Vox::value);
int count = 0;
for( Vector<Vox>::Iterator it = vc.begin(); it < vc.end(); it++ ) {
acc.Set(it,count++);
std::cout << " -> " << acc.Get(it) << "\n";
}
}
END_TESTING;
}

View File

@@ -38,6 +38,7 @@ namespace uLib {
//// INTERFACE TO COMPLEX CLASS /////
namespace Interface {
struct Test {
MAKE_TRAITS
template<class Self> void check_structural() {
@@ -45,30 +46,38 @@ struct Test {
uLibCheckMember(Self,testmemb,int);
}
};
} // Interface
struct Test {
bool test(int i, float f){}
int testmemb;
};
struct NoTest {
bool test(int i, float f){}
float testmemb;
};
/////////////////////////
template <class T>
class UseTest {
public:
UseTest() {
Interface::IsA<T,Interface::Test>();
T t;
int i; float f;
t.test(i,f);
}
};
//template <class T>
//class UseTest {
//public:
// UseTest() {
// Interface::IsA<T,Interface::Test<T> >();
// T t;
// int i; float f;
// t.test(i,f);
// }
//};
template <class T>
class UseTest2 {
Interface::StaticIsA<T, Interface::Test> x;
static Interface::StaticIsA<T, Interface::Test > check;
public:
UseTest2() {
T t;
@@ -87,9 +96,9 @@ int main()
{
BEGIN_TESTING(Static Interface);
UseTest<Test> u;
// UseTest<Test> u;
UseTest2<Test> u2;
UseTest2<NoTest> u2;
END_TESTING;
}

View File

@@ -26,6 +26,14 @@
#include <stdio.h>
#include <stdlib.h>
namespace uLib {
namespace detail {
} // detail
} // uLib
#define BEGIN_TESTING(name) \
static int _fail = 0; \