Files
uLib/src/Math/BitCode.h
Andrea Rigoni 99e771a223 [uLib Geometry]
non working version!

+ adds ProgrammableAccessor
+ renaming of some Image structures ...
2014-11-03 10:27:52 +00:00

260 lines
7.5 KiB
C++

/*//////////////////////////////////////////////////////////////////////////////
// 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.
//////////////////////////////////////////////////////////////////////////////*/
#ifndef U_MATH_BITCODE_H
#define U_MATH_BITCODE_H
#include <boost/static_assert.hpp>
#include <boost/type_traits.hpp>
//#include <Core/CommaInitializer.h>
#include <Math/Dense.h>
#include <Core/Mpl.h>
#include <boost/mpl/vector_c.hpp>
#include <boost/mpl/size.hpp>
#include <boost/mpl/set_c.hpp>
namespace uLib {
template < typename ContainerT, typename ContentT >
struct CommaInitializerBitCode
{
inline explicit CommaInitializerBitCode(ContainerT *container, ContentT s)
: container(container)
{
this->index = 0;
this->container->operator()().field1 = s;
}
inline CommaInitializerBitCode & operator, (ContentT s) {
this->index++;
if(index < container->size()) {
if(index == 1) container->operator()().field2 = s;
if(index == 2) container->operator()().field3 = s;
if(index == 3) container->operator()().field4 = s;
}
return *this;
}
ContainerT *container;
unsigned int index;
};
template <typename T, uint L1, uint L2>
class BitCode2
{
protected:
typedef T Type;
typedef BitCode2<T,L1,L2> ThisClass;
typedef CommaInitializerBitCode< ThisClass, T > CommaInit;
BOOST_STATIC_ASSERT_MSG( boost::is_unsigned<T>::value == 1, "CODE TYPE MUST BE UNSIGNED" );
BOOST_STATIC_ASSERT( L1+L2 == sizeof(T)*8 );
public:
struct BitField {
T field1 : L1;
T field2 : L2;
};
union CodeSet {
BitField bitf;
T value;
} m_data;
BitCode2() {}
BitCode2(const T& data) { m_data.value = data; }
BitCode2(const Vector2i & data) {
(*this) << data(0),data(1);
}
inline CommaInit operator <<(T scalar) { return CommaInit(this, scalar); }
static const int size() { return 2; }
BitField & operator()() { return m_data.bitf; }
const BitField & operator()() const { return m_data.bitf; }
operator Vector2i () { return Vector2i(m_data.bitf.field1,
m_data.bitf.field2); }
void set(const T data) { m_data.value = data; }
T get() const { return m_data.value; }
};
template <typename T, uint L1, uint L2>
std::ostream &
operator << (std::ostream &o, const BitCode2<T,L1,L2> &code) {
o << code().field1 << "," << code().field2;
return o;
}
template <typename T, uint L1, uint L2, uint L3>
class BitCode3
{
protected:
typedef T Type;
typedef BitCode3<T,L1,L2,L3> ThisClass;
typedef CommaInitializerBitCode< ThisClass, T > CommaInit;
BOOST_STATIC_ASSERT_MSG( boost::is_unsigned<T>::value == 1, "CODE TYPE MUST BE UNSIGNED" );
BOOST_STATIC_ASSERT( L1+L2+L3 == sizeof(T)*8 );
public:
struct BitField {
T field1 : L1;
T field2 : L2;
T field3 : L3;
};
union CodeSet {
BitField bitf;
T value;
} m_data;
BitCode3() {}
BitCode3(const T& data) { m_data.value = data; }
BitCode3(const Vector3i & data) {
(*this) << data(0),data(1),data(2);
}
inline CommaInit operator <<(T scalar) { return CommaInit(this, scalar); }
static const int size() { return 3; }
BitField & operator()() { return m_data.bitf; }
const BitField & operator()() const { return m_data.bitf; }
operator Vector3i () { return Vector3i(m_data.bitf.field1,
m_data.bitf.field2,
m_data.bitf.field3); }
void set(const T data) { m_data.value = data; }
T get() const { return m_data.value; }
};
template <typename T, uint L1, uint L2, uint L3>
std::ostream &
operator << (std::ostream &o, const BitCode3<T,L1,L2,L3> &code) {
o << code().field1 << "," << code().field2 << "," << code().field3;
return o;
}
template <typename T, uint L1, uint L2, uint L3, uint L4>
class BitCode4
{
protected:
typedef T Type;
typedef BitCode4<T,L1,L2,L3,L4> ThisClass;
typedef CommaInitializerBitCode< ThisClass, T > CommaInit;
BOOST_STATIC_ASSERT_MSG( boost::is_unsigned<T>::value == 1, "CODE TYPE MUST BE UNSIGNED" );
BOOST_STATIC_ASSERT( L1+L2+L3+L4 == sizeof(T)*8 );
public:
struct BitField {
T field1 : L1;
T field2 : L2;
T field3 : L3;
T field4 : L4;
};
union CodeSet {
BitField bitf;
T value;
} m_data;
BitCode4() {}
BitCode4(const T& data) { m_data.value = data; }
BitCode4(const Vector4i & data) {
(*this) << data(0),data(1),data(2),data(3);
}
inline CommaInit operator << (T scalar) { return CommaInit(this, scalar); }
static const int size() { return 4; }
BitField & operator()() { return m_data.bitf; }
const BitField & operator()() const { return m_data.bitf; }
operator Vector4i () { return Vector4i(m_data.bitf.field1,
m_data.bitf.field2,
m_data.bitf.field3,
m_data.bitf.field4); }
void set(const T data) { m_data.value = data; }
T get() const { return m_data.value; }
};
template <typename T, uint L1, uint L2, uint L3, uint L4>
std::ostream &
operator << (std::ostream &o, const BitCode4<T,L1,L2,L3,L4> &code) {
o << code().field1 << "," << code().field2 << "," << code().field3 << "," << code().field4;
return o;
}
template <typename T, uint L1, uint L2 = 0, uint L3 = 0>
class BitCode {
typedef boost::mpl::vector_c<T,L1,L2,L3> BitSet;
typedef boost::mpl::vector_c<T,0,L1,L1+L2> BitSft;
// static constexpr uint bset[3] = {L1,L2,L3};
// static constexpr uint bsft[3] = {0,L1,L1+L2};
BOOST_STATIC_ASSERT_MSG( boost::is_unsigned<T>::value == 1, "CODE TYPE MUST BE UNSIGNED" );
//BOOST_STATIC_ASSERT( L1+L2+L3 == sizeof(T)*8 );
T m_data;
public:
void PrintSelf( ) {
// for(int i=0; i< boost::mpl::size<BitSet>() ;++i)
// std::cout << "BitSet " << i << " [" << bset[i] << "] -> " << Get(i) << "\n";
}
T Get(unsigned short field) const {
// return (m_data >> bsft[field]) & (1<<bset[field]-1);
}
void Set(unsigned short field, const T data) {
// TODO: optimize Set BitCode
// T mask = (1<<bset[field]-1) << bsft[field];
// T d1 = (data << bsft[field]) & mask;
// T d2 = m_data & !mask;
// m_data = d1 | d2;
}
};
} // uLib
#endif // BITCODE_H