[uLib Geometry]

+ adds ClassCompound pattern
This commit is contained in:
Andrea Rigoni
2014-12-03 18:38:57 +00:00
parent 65be7b6726
commit ff208205f8
7 changed files with 488 additions and 155 deletions

View File

@@ -24,6 +24,7 @@ set(HEADERS
ProgrammableAccessor.h
Named.h
MplSequenceCombiner.h
ClassCompound.h
)
SET(SOURCES

175
src/Core/ClassCompound.h Normal file
View File

@@ -0,0 +1,175 @@
#ifndef U_CORE_CLASSCOMPOUND_H
#define U_CORE_CLASSCOMPOUND_H
#include "boost/type_traits.hpp"
#include "Core/Mpl.h"
namespace uLib {
namespace detail {
template < class _Seq >
struct ClassCompound : ULIB_MPL_INHERIT_SEQ(_Seq) {
typedef _Seq Seq;
ClassCompound() {}
template < class S >
struct CopyOp {
CopyOp(const S * src, ClassCompound * const dst) : m_src(src), m_dst(dst) {}
template < class T, bool b >
void copy(const T &t, const boost::integral_constant<bool,b>&) const {
}
template < class T >
void copy(const T &t, const boost::true_type&) const {
static_cast<T &>(*m_dst) = t;
}
template < class A >
void operator()(A) const {
const A &t = *m_src;
copy(t, boost::is_base_of<A,ClassCompound>());
}
ClassCompound * const m_dst;
const S *m_src;
};
template < class Other >
ClassCompound(const Other &t) {
typedef typename Other::Seq _seq;
mpl::for_each<_seq>(CopyOp<Other>(&t,this));
}
template < class Other >
const ClassCompound & operator = (const Other &t) {
typedef typename Other::Seq _seq;
mpl::for_each<_seq>(CopyOp<Other>(&t,this));
return *this;
}
};
} // detail
struct Null {};
template < class T0 = Null,
class T1 = Null,
class T2 = 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;
//NEVER REACHED //
};
template < class _A0 >
struct ClassCompound<_A0> : detail::ClassCompound< mpl::vector<_A0> > {
typedef detail::ClassCompound< mpl::vector<_A0> > BaseClass;
typedef _A0 A1;
ClassCompound() {}
template < class Other >
ClassCompound(const Other &t) : BaseClass(t) {}
using BaseClass::operator =;
};
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;
ClassCompound() {}
template < class Other >
ClassCompound(const Other &t) : BaseClass(t) {}
using BaseClass::operator =;
};
template < class _A0,
class _A1,
class _A2 >
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;
ClassCompound() {}
template < class Other >
ClassCompound(const Other &t) : BaseClass(t) {}
using BaseClass::operator =;
};
template < class _A0,
class _A1,
class _A2,
class _A3 >
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;
ClassCompound() {}
template < class Other >
ClassCompound(const Other &t) : BaseClass(t) {}
using BaseClass::operator =;
};
template < class _A0,
class _A1,
class _A2,
class _A3,
class _A4 >
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;
ClassCompound() {}
template < class Other >
ClassCompound(const Other &t) : BaseClass(t) {}
using BaseClass::operator =;
};
} // uLib
#endif // CLASSCOMPOUND_H

View File

@@ -19,12 +19,11 @@ namespace uLib {
////////////////////////////////////////////////////////////////////////////////
// generator //
template <class BaseType, class T>
static BaseType * newClass() { return new T; }
template <class T>
static void * newClass() { return new T; }
template <class T>
static void * newClass2(void *a1,void *a2) { return new T(a1,a2); }
@@ -34,18 +33,18 @@ static BaseType * newClass() { return new T; }
template <class BaseType>
class NamedClassFactory {
typedef BaseType*(*_newClassfn)();
typedef void * (*_newClassfn)();
typedef std::map<const char*,_newClassfn> MapType;
public:
template<typename Type>
void AddType(const char* name) {
m_map.insert(std::make_pair(name, &newClass<BaseType,Type>));
m_map.insert(std::make_pair(name, &newClass<Type>));
}
BaseType *Create(const char *type) {
typename MapType::iterator itr = m_map.find(type);
return itr->second();
return static_cast<BaseType*>(itr->second());
}
void List(std::ostream &o) {
@@ -67,7 +66,7 @@ private:
template <class BaseType, typename RegSeqT>
class RegisteredClassFactory {
typedef BaseType*(*_newClassfn)();
typedef void *(*_newClassfn)();
typedef std::vector<_newClassfn> TypeVectorType;
struct AddTypeOp {
@@ -79,7 +78,7 @@ class RegisteredClassFactory {
};
template < typename T >
void addType() { m_map.push_back(&newClass<BaseType,T>); }
void addType() { m_map.push_back(&newClass<T>); }
public:
@@ -97,7 +96,7 @@ public:
BaseType *Create() {
int id = Find<T>();
typename TypeVectorType::iterator itr = m_map.begin() + id;
return (*itr)();
return (BaseType *)(*itr)();
}
private:
@@ -116,12 +115,12 @@ template <
typename S1
>
class RegisteredClassFactory1 {
typedef BaseType*(*_newClassfn)();
typedef void*(*_newClassfn)();
typedef std::vector<_newClassfn> TypeVectorType;
template < typename U >
void addType() { m_map.push_back(&newClass<
BaseType,
// BaseType,
DerivedType<U>
>); }
@@ -151,7 +150,7 @@ public:
BaseType *Create(int id1) {
typename TypeVectorType::iterator itr = m_map.begin() + id1;
return (*itr)();
return (BaseType *)(*itr)();
}
private:
@@ -174,12 +173,12 @@ template <
typename S2
>
class RegisteredClassFactory2 {
typedef BaseType*(*_newClassfn)();
typedef void*(*_newClassfn)();
typedef std::vector<_newClassfn> TypeVectorType;
template < typename U, typename V >
void addType() { m_map.push_back(&newClass<
BaseType,
// BaseType,
DerivedType<U,V>
>); }
@@ -196,12 +195,20 @@ 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() {
mpl::for_each< AlgView >(AddTypeSeqOp(this));
}
template < typename T >
static inline int FindS1() {
typedef typename mpl::find<S1,T>::type iter;
@@ -215,9 +222,9 @@ public:
}
BaseType *Create(int id1, int id2) {
BaseType * Create(int id1, int id2) {
typename TypeVectorType::iterator itr = m_map.begin() + id1 + m_size1 * id2;
return (*itr)();
return (BaseType *)(*itr)();
}
private:
@@ -243,12 +250,12 @@ template <
typename S3
>
class RegisteredClassFactory3 {
typedef BaseType*(*_newClassfn)();
typedef void*(*_newClassfn)();
typedef std::vector<_newClassfn> TypeVectorType;
template < typename T1, typename T2, typename T3 >
void addType() { m_map.push_back(&newClass<
BaseType,
// BaseType,
DerivedType<T1,T2,T3>
>); }
@@ -293,7 +300,7 @@ public:
BaseType *Create(int id1, int id2, int id3) {
typename TypeVectorType::iterator itr = m_map.begin() + id1 + m_size1 * id2 + m_size1 * m_size3 * id3;
return (*itr)();
return (BaseType *)(*itr)();
}
private:

View File

@@ -56,6 +56,9 @@
#include <boost/utility/enable_if.hpp>
/**
* Max size of nofold inerited capability
*/

View File

@@ -24,6 +24,7 @@ set( TESTS
ProgrammableAccessorTest
ClassFactoryTest
MplSequenceCombinerTest
ClassCompoundTest
)
set(LIBRARIES

View File

@@ -0,0 +1,215 @@
/*//////////////////////////////////////////////////////////////////////////////
// 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/Vector.h"
#include "Core/ClassCompound.h"
#include "testing-prototype.h"
using namespace uLib;
////////////////////////////////////////////////////////////////////////////////
// WORKING EXAMPLE //
namespace Test {
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 ClassCompound< VoxType, CounterType >
{
typedef ClassCompound< VoxType, 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));
}
}
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;
}
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);
}
int Size() const { return m_data.size(); }
int Count() const {
return CounterType::Count(m_data);
}
private:
friend class VoxelVectorFactory;
Vector<VoxType> m_data;
};
} // Test
using namespace Test;
int main() {
VoxelVector< VoxelMean, VoxCountOver > img;
img.Set(0,555);
img.Set(1,23);
img.Set(1,25);
img.Set(2,68);
img.A1::m_threshold = 50;
std::cout << "-> ";
for(int i=0; i<3; ++i) {
std::cout << img.Get(i) << " ";
}
std::cout << " count: " << img.Count() << "\n";
VoxelVector< VoxelVal, VoxCountOver > img2 = img;
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: " << img2.Count() << "\n";
}

View File

@@ -24,133 +24,23 @@
//////////////////////////////////////////////////////////////////////////////*/
#include <iostream>
//#include "boost/preprocessor.hpp"
//#include "boost/preprocessor/repetition.hpp"
#include "Core/MplSequenceCombiner.h"
#include "Core/ClassCompound.h"
#include "Core/ClassFactory.h"
#include "Core/Serializable.h"
#include "testing-prototype.h"
using namespace uLib;
//namespace {
class Base {
public:
Base() {}
Base(const Base &copy) {}
virtual void Go() {}
};
class Derived : public Base {
public:
void Go() { std::cout << "Derived Go\n"; }
};
class Derived2 : public Base {
public:
void Go() { std::cout << "Derived2 Go\n"; }
};
class Derived3 : public Base {
public:
void Go() { std::cout << "Derived3 Go\n"; }
};
class Derived4 : public Base {
public:
void Go() { std::cout << "Derived4 Go\n"; }
};
template <
class A1,
class A2
>
class AlgHolder : public Base {
A1 m_a1;
A2 m_a2;
public:
void Go() {
std::cout << "AlgHolder Go: \n";
std::cout << " A1 -> "; m_a1.Go();
std::cout << " A2 -> "; m_a2.Go();
}
};
//}
typedef mpl::vector< Derived, Derived2, Derived3, Derived4 > seq;
class ProgrammableAlgHolder {
public:
ProgrammableAlgHolder() : m_id1(0), m_id2(0)
{ m_base = m_factory.Create(0,0); }
template < typename T >
void SetA1(const T *alg = NULL) {
int id = m_factory.FindS1<T>();
Base * newbase = m_factory.Create(id,m_id2);
*newbase = *m_base;
delete m_base;
m_base = newbase;
}
template < typename T >
void SetA2(const T *alg = NULL) {
int id = m_factory.FindS2<T>();
Base * newbase = m_factory.Create(m_id1,id);
*newbase = *m_base;
delete m_base;
m_base = newbase;
}
Base * operator -> () { return m_base; }
private:
RegisteredClassFactory2<Base, AlgHolder, seq, seq> m_factory;
int m_id1, m_id2;
Base * m_base;
};
//int main() {
// ProgrammableAlgHolder ah;
// ah.SetA1<Derived4>();
// ah->Go();
// return 0;
//}
////////////////////////////////////////////////////////////////////////////////
// WORKING EXAMPLE //
@@ -190,7 +80,7 @@ private:
class VoxCount {
public:
template < class T >
int Count(const Vector<T> &ref ) {
int Count(const Vector<T> &ref ) const {
return ref.size();
}
};
@@ -200,7 +90,7 @@ public:
VoxCountOver() : m_threshold(0) {}
template < class T >
int Count(const Vector<T> &ref ) {
int Count(const Vector<T> &ref ) const {
int count = 0 ;
foreach (const T &el, ref) {
if( el.Get() >= m_threshold ) ++count;
@@ -236,6 +126,16 @@ 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);
@@ -250,11 +150,18 @@ private:
};
class VoxelVectorFactory {
public:
VoxelVectorFactory() : m_id1(0), m_id2(0) { m_base = m_factory.Create(0,0); }
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 >
@@ -262,6 +169,9 @@ public:
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;
}
@@ -271,7 +181,9 @@ public:
int id = m_factory.FindS2<T>();
VoxelVectorBase * newbase = m_factory.Create(m_id1,id);
Test::copy(m_base,newbase); // *newbase = *m_base;
// ????? come copiare i membri ???? ////
//
delete m_base;
m_base = newbase;
}
@@ -289,22 +201,41 @@ private:
struct B1 {
B1() : m_b1(1) {}
int m_b1;
};
struct B2 {
B2() : m_b2(2) {}
int m_b2;
};
struct B3 {
B3() : m_b3(3) {}
int m_b3;
};
struct B3b {
B3b() : m_b3(3) {}
int m_b3; // learn to handle ambiguity ..
};
int main() {
Test::VoxelVectorFactory factory;
for(int i=0; i<10; ++i)
factory->Set(i,i);
factory.SetVoxel<Test::VoxelVal>();
for(int i=0; i<10; ++i)
std::cout << factory->Get(i) << " ";
std::cout << "\n";
std::cout << "vox count = " << factory->Count() << "\n";
ClassCompound< B1, B2 > h1;
ClassCompound< B2, B3, B1 > h2;
h1.A0::m_b1 = 111;
h1.A1::m_b2 = 222;
h2 = h1;
std::cout << "h1: " << h1.A0::m_b1 << " " << h1.A1::m_b2 << "\n";
std::cout << "h2: " << h2.A0::m_b2 << " " << h2.A1::m_b3 << "\n";
}