mirror of
https://github.com/OpenCMT/uLib.git
synced 2025-12-06 07:21:31 +01:00
[uLib geometry]
- adds some to Programmable accessors - Static interface test - Mpl sequence
This commit is contained in:
@@ -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 ©) {
|
||||
typedef typename Other::Seq _seq;
|
||||
mpl::for_each<_seq>(CopyOp<Other>(&t,this));
|
||||
mpl::for_each<_seq>(CopyOp<Other>(©,this));
|
||||
}
|
||||
|
||||
template < class Other >
|
||||
const ClassCompound & operator = (const Other &t) {
|
||||
inline void copy ( const Other © ) throw () {
|
||||
typedef typename Other::Seq _seq;
|
||||
mpl::for_each<_seq>(CopyOp<Other>(&t,this));
|
||||
mpl::for_each<_seq>(CopyOp<Other>(©,this));
|
||||
}
|
||||
|
||||
template < class Other >
|
||||
const ClassCompound & operator = (const Other ©) {
|
||||
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,8 +135,10 @@ 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() {}
|
||||
|
||||
@@ -105,6 +146,7 @@ struct ClassCompound<_A0,_A1> : detail::ClassCompound< mpl::vector<_A0,_A1> > {
|
||||
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() {}
|
||||
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 //
|
||||
|
||||
@@ -23,8 +23,10 @@ set( TESTS
|
||||
OptionsTest
|
||||
ProgrammableAccessorTest
|
||||
ClassFactoryTest
|
||||
ClassFactoryRuntimeTest
|
||||
MplSequenceCombinerTest
|
||||
ClassCompoundTest
|
||||
MplSequenceReplaceElTest
|
||||
)
|
||||
|
||||
set(LIBRARIES
|
||||
|
||||
@@ -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 ©) : 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";
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
246
src/Core/testing/ClassFactoryRuntimeTest.cpp
Normal file
246
src/Core/testing/ClassFactoryRuntimeTest.cpp
Normal 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();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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 ..
|
||||
};
|
||||
|
||||
|
||||
int main() {
|
||||
|
||||
ClassCompound< B1, B2 > h1;
|
||||
ClassCompound< B2, B3, B1 > h2;
|
||||
|
||||
|
||||
h1.A0::m_b1 = 111;
|
||||
h1.A1::m_b2 = 222;
|
||||
struct HB {
|
||||
virtual ~HB() {}
|
||||
virtual void Print() = 0;
|
||||
};
|
||||
|
||||
h2 = h1;
|
||||
template <
|
||||
class A0,
|
||||
class A1
|
||||
>
|
||||
struct H : HB, ClassCompound<A0,A1> {
|
||||
typedef ClassCompound<A0,A1> Compound;
|
||||
|
||||
std::cout << "h1: " << h1.A0::m_b1 << " " << h1.A1::m_b2 << "\n";
|
||||
std::cout << "h2: " << h2.A0::m_b2 << " " << h2.A1::m_b3 << "\n";
|
||||
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() {
|
||||
|
||||
B1 b1;
|
||||
B2 b2;
|
||||
B3 b3;
|
||||
B3b b3b;
|
||||
|
||||
b1.m_b1 = 111;
|
||||
b2.m_b2 = 222;
|
||||
b3.m_b3 = 333;
|
||||
b3b.m_b3 = 333;
|
||||
|
||||
|
||||
H<B1,B2> h12;
|
||||
h12.A0() = b1;
|
||||
|
||||
H<B1,B3> h13 = h12.SetComponent<1>(b3);
|
||||
h13.Print();
|
||||
|
||||
{
|
||||
H<B1,B2> h12 = CompoundFactory<BB,BB>::create(b1,b2);
|
||||
h12.Print();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
} // Test
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
60
src/Core/testing/MplSequenceReplaceElTest.cpp
Normal file
60
src/Core/testing/MplSequenceReplaceElTest.cpp
Normal 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;
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
#include <iterator>
|
||||
|
||||
namespace uLib {
|
||||
namespace Test {
|
||||
|
||||
class TestVoxel {
|
||||
public:
|
||||
@@ -23,17 +23,65 @@ 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;
|
||||
|
||||
{ // TEST 1
|
||||
Vector<TestVoxel> v;
|
||||
v.push_back(TestVoxel());
|
||||
v.push_back(TestVoxel());
|
||||
@@ -49,15 +97,85 @@ int main() {
|
||||
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<float>() << "\n";
|
||||
std::cout << " -> " << f2.Get(&el) /*<< " - " << f1(&el).Get()*/ << "\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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -26,6 +26,14 @@
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
namespace uLib {
|
||||
namespace detail {
|
||||
|
||||
} // detail
|
||||
} // uLib
|
||||
|
||||
#define BEGIN_TESTING(name) \
|
||||
static int _fail = 0; \
|
||||
|
||||
@@ -33,6 +33,8 @@
|
||||
|
||||
#include "Math/Dense.h"
|
||||
#include "Math/StructuredData.h"
|
||||
|
||||
#include <Core/ClassCompound.h>
|
||||
#include <Core/ProgrammableAccessor.h>
|
||||
|
||||
#include <vtkInformation.h>
|
||||
@@ -41,61 +43,162 @@
|
||||
namespace uLib {
|
||||
|
||||
|
||||
//typedef std::iterator SequenceIterator;
|
||||
|
||||
//template < typename T >
|
||||
//struct Enumeration {
|
||||
|
||||
//};
|
||||
|
||||
//template < typename T >
|
||||
//struct Iterator {
|
||||
|
||||
//};
|
||||
|
||||
//class AbstractDenseSequence {
|
||||
//public:
|
||||
|
||||
// virtual bool Empty() const = 0;
|
||||
|
||||
|
||||
//};
|
||||
|
||||
|
||||
class AbstractArray {
|
||||
public:
|
||||
virtual void * GetDataPointer(Id_t id) const = 0;
|
||||
virtual const void * GetDataPointer(Id_t id) const = 0;
|
||||
virtual void * GetDataPointer(Id_t id) = 0;
|
||||
virtual void SetSize(const size_t size) = 0;
|
||||
virtual const size_t GetSize() const = 0;
|
||||
virtual ~AbstractArray() {}
|
||||
};
|
||||
|
||||
|
||||
class DataSetAttributes {
|
||||
public:
|
||||
|
||||
template < typename GeT, typename SeT >
|
||||
inline void SetScalars(GeT get, SeT set) {
|
||||
m_Scalars.SetAccessFunctions(get,set);
|
||||
template < typename T >
|
||||
class DataAttributes {
|
||||
public:
|
||||
template < typename F >
|
||||
void AddAttribute(const char *name, F f) {
|
||||
ProgrammableAccessor<T> pa(name);
|
||||
pa.SetAccessFunctions(f);
|
||||
m_Accessors.push_back(pa);
|
||||
if(m_Accessors.size() == 1)
|
||||
SetActive(name);
|
||||
}
|
||||
|
||||
template < typename F1, typename F2 >
|
||||
void AddAttribute(const char *name, F1 f1, F2 f2) {
|
||||
ProgrammableAccessor<T> pa(name);
|
||||
pa.SetAccessFunctions(f1,f2);
|
||||
m_Accessors.push_back(pa);
|
||||
if(m_Accessors.size() == 1)
|
||||
SetActive(name);
|
||||
}
|
||||
|
||||
ProgrammableAccessor<T> * GetAttribute(const char *name) /*const*/ {
|
||||
foreach (ProgrammableAccessor<T> &el, m_Accessors) {
|
||||
if(el.GetName() == name)
|
||||
return ⪙
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void SetActive(const char *name) {
|
||||
m_Active = this->GetAttribute(name);
|
||||
}
|
||||
uLibGetMacro(Active,ProgrammableAccessor<T> *)
|
||||
uLibRefMacro(Accessors, Vector< ProgrammableAccessor<T> >);
|
||||
private:
|
||||
ProgrammableAccessor<double> m_Scalars;
|
||||
Vector< ProgrammableAccessor<T> > m_Accessors;
|
||||
ProgrammableAccessor<T> *m_Active;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
template < typename T >
|
||||
class DataVector : public AbstractArray {
|
||||
class DataSet : public AbstractArray {
|
||||
public:
|
||||
void * GetDataPointer(Id_t id) const { return (void *)&m_Data.at(id); }
|
||||
DataSet() {}
|
||||
virtual ~DataSet() {}
|
||||
|
||||
template < typename F >
|
||||
inline void AddScalarAccess(const char *name, F f) { Scalars().AddAttribute(name,f); }
|
||||
|
||||
template < typename F1, typename F2 >
|
||||
inline void AddScalarAccess(const char *name, F1 f1, F2 f2) { Scalars().AddAttribute(name,f1,f2); }
|
||||
|
||||
double GetScalar(int id) {
|
||||
ProgrammableAccessor<double> *acc = Scalars().GetActive();
|
||||
if (acc) return acc->Get(this->GetDataPointer(id));
|
||||
}
|
||||
|
||||
double GetScalar(const char *name, int id) {
|
||||
ProgrammableAccessor<double> *acc = Scalars().GetAttribute(name);
|
||||
if (acc) return acc->Get(this->GetDataPointer(id));
|
||||
}
|
||||
|
||||
void SetScalar(int id, double val) {
|
||||
ProgrammableAccessor<double> *acc = Scalars().GetActive();
|
||||
if (acc) acc->Set(this->GetDataPointer(id),val);
|
||||
}
|
||||
|
||||
void SetScalar(const char *name, int id, double val) {
|
||||
ProgrammableAccessor<double> *acc = Scalars().GetAttribute(name);
|
||||
if (acc) acc->Set(this->GetDataPointer(id),val);
|
||||
}
|
||||
|
||||
inline void SetActiveScalars(const char *name) { Scalars().SetActive(name); }
|
||||
inline ProgrammableAccessor<double> * GetActiveScalars() { return Scalars().GetActive(); }
|
||||
|
||||
|
||||
uLibRefMacro(Scalars,DataAttributes< double >);
|
||||
uLibRefMacro(Vectors,DataAttributes< Vector3d >);
|
||||
private:
|
||||
DataAttributes< double > m_Scalars;
|
||||
DataAttributes< Vector3d > m_Vectors; // da finire ... //
|
||||
};
|
||||
|
||||
|
||||
template <
|
||||
typename T,
|
||||
class ScalarAccess
|
||||
>
|
||||
class DataVectorCompound :
|
||||
public DataSet,
|
||||
public ClassCompound< ScalarAccess >
|
||||
{
|
||||
typedef DataVectorCompound<T,ScalarAccess> ThisClass;
|
||||
typedef ClassCompound< ScalarAccess > Compound;
|
||||
typedef T DataType;
|
||||
|
||||
public:
|
||||
DataVectorCompound() {}
|
||||
|
||||
template < class Other >
|
||||
DataVectorCompound(const Other &cp) :
|
||||
Compound(cp),
|
||||
m_Data(cp.Data())
|
||||
{}
|
||||
|
||||
const void * GetDataPointer(Id_t id) const { return (const void *)&m_Data.at(id); }
|
||||
void * GetDataPointer(Id_t id) { return (void *)&m_Data.at(id); }
|
||||
|
||||
inline DataType & operator [] (Id_t id) { return m_Data.operator [](id); }
|
||||
inline const DataType & operator [] (Id_t id) const { return m_Data.operator [](id); }
|
||||
|
||||
inline void SetSize(const size_t size) { m_Data.resize(size); }
|
||||
inline const size_t GetSize() const { return m_Data.size(); }
|
||||
|
||||
uLibRefMacro(Data,Vector<T>)
|
||||
uLibRefMacro(Attributes,DataSetAttributes)
|
||||
uLibRefMacro(Data,Vector<DataType>)
|
||||
uLibConstRefMacro(Data,Vector<T>)
|
||||
private:
|
||||
DataSetAttributes m_Attributes;
|
||||
Vector<T> m_Data;
|
||||
Vector<DataType> m_Data;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//class DataSet {
|
||||
//public:
|
||||
|
||||
// virtual Vector3d GetPoint(const Id_t) const = 0;
|
||||
// virtual Vector<Id_t> GetCell(const Id_t) const = 0;
|
||||
|
||||
//private:
|
||||
//};
|
||||
|
||||
|
||||
|
||||
|
||||
} // uLib
|
||||
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
#include "Core/Macros.h"
|
||||
#include "Core/Object.h"
|
||||
#include "Math/Dense.h"
|
||||
#include "Math/DataSet.h"
|
||||
//#include "Math/DataSet.h"
|
||||
|
||||
//#include "boost/range.hpp"
|
||||
//#include "boost/range/iterator.hpp"
|
||||
|
||||
@@ -25,8 +25,10 @@
|
||||
|
||||
|
||||
#include "testing-prototype.h"
|
||||
|
||||
|
||||
#include "Math/DataSet.h"
|
||||
#include "Math/ImageData.h"
|
||||
#include <Core/Mpl.h>
|
||||
|
||||
#include <root/TRandom.h>
|
||||
|
||||
@@ -35,59 +37,74 @@ using namespace uLib;
|
||||
namespace {
|
||||
struct MyVoxel {
|
||||
MyVoxel() : value(0), count(0) {}
|
||||
MyVoxel(float v, int c) : value(v), count(c) {}
|
||||
float value;
|
||||
int count;
|
||||
};
|
||||
|
||||
|
||||
struct VoxelMean : public MyVoxel {
|
||||
VoxelMean() {}
|
||||
void SetValue(const float _value) { value += _value; ++count; }
|
||||
float GetValue() const { return value/count; }
|
||||
struct MyVoxelMeanAccess {
|
||||
static void Set(MyVoxel &vox, double val) {
|
||||
vox.value = val;
|
||||
++vox.count;
|
||||
}
|
||||
static double Get(const MyVoxel &vox) { return vox.value/vox.count; }
|
||||
};
|
||||
|
||||
struct MyVoxelValueAccess {
|
||||
static void Set(MyVoxel &vox, double val) {
|
||||
vox.value = val;
|
||||
vox.count = 1;
|
||||
}
|
||||
static double Get(const MyVoxel &vox) { return vox.value; }
|
||||
};
|
||||
|
||||
struct MyVoxelJitterAccess {
|
||||
MyVoxelJitterAccess() : min(-1), max(1) { srand (static_cast <unsigned> (time(0))); }
|
||||
MyVoxelJitterAccess(float min, float max) : min(min), max(max) { srand (static_cast <unsigned> (time(0))); }
|
||||
|
||||
float random() const {
|
||||
return min + static_cast <float> (rand()) / ( static_cast <float> (RAND_MAX/(max-min)));
|
||||
}
|
||||
|
||||
void Set(MyVoxel &vox, double val) {
|
||||
vox.value = val + random();
|
||||
vox.count = 1;
|
||||
}
|
||||
double Get(const MyVoxel &vox) const { return vox.value / vox.count + random(); }
|
||||
|
||||
float min, max;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
int main() {
|
||||
|
||||
// DataVector<MyVoxel> v;
|
||||
DataVectorCompound< MyVoxel, MyVoxelMeanAccess > data;
|
||||
data.Data().push_back( MyVoxel(5,1) );
|
||||
data.Data().push_back( MyVoxel(10,2) );
|
||||
data.Data().push_back( MyVoxel(15,3) );
|
||||
data.Data().push_back( MyVoxel(2368,1) );
|
||||
|
||||
DataVectorImage img;
|
||||
data[3].value = 123;
|
||||
|
||||
// img.Data() = v;
|
||||
// img.Scalars().SetAccessFunctions(&MyVoxel::value);
|
||||
// img.SetDims(Vector3i(3,3,3));
|
||||
DataVectorCompound< MyVoxel, MyVoxelValueAccess > data2 = data;
|
||||
|
||||
// for (int x=0; x<img.GetDims().prod(); ++x){
|
||||
// img.SetValue(x,x);
|
||||
// std::cout << img.UnMap(x).transpose() << " -> " << img.GetValue(x) << "\n";
|
||||
// }
|
||||
|
||||
DataVector<VoxelMean> vm;
|
||||
|
||||
Vector<VoxelMean> vm_2;
|
||||
vm_2.resize(Vector3i(300,300,300).prod());
|
||||
|
||||
img.Data() = vm;
|
||||
img.SetDims(Vector3i(300,300,300));
|
||||
img.Scalars().SetAccessFunctions(&VoxelMean::GetValue,&VoxelMean::SetValue);
|
||||
|
||||
// TRandom random;
|
||||
|
||||
|
||||
for(int i=0; i< 100; ++i)
|
||||
for (int x=0; x<img.GetDims().prod(); ++x){
|
||||
// vm.Data()[x].value += 1; vm.Data()[x].count++;
|
||||
// vm.Data()[x].SetValue(1);
|
||||
vm_2[x].SetValue(1);
|
||||
// img.SetValue(x,1);
|
||||
// boost::bind(&VoxelMean::SetValue,&vm.Data()[x], _1)(1);
|
||||
// std::cout << img.UnMap(x).transpose() << " -> " << img.GetValue(x) << "\n";
|
||||
std::cout << "image data test \n";
|
||||
foreach (MyVoxel &el, data2.Data()) {
|
||||
std::cout << "-> " << el.value << " - " << el.count << "\n";
|
||||
}
|
||||
|
||||
// img.ExportToVtk("test.vtk");
|
||||
DataVectorCompound< MyVoxel, MyVoxelJitterAccess > data3 = data2;
|
||||
data3.A0().min = -1;
|
||||
data3.A0().max = 1;
|
||||
data3.AddScalarAccess("scalars",&MyVoxel::value);
|
||||
data3.AddScalarAccess("counts",&MyVoxel::count);
|
||||
|
||||
std::cout << "image data test \n";
|
||||
for(int i=0; i<data3.GetSize(); ++i) {
|
||||
std::cout << " -> " << data3.GetScalar(i) << " - " << data3.GetScalar("counts",i) << "\n";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user