Improved the ana serializer implementation with helpers for containers.
This commit is contained in:
parent
784cf12b97
commit
85a65de531
1 changed files with 140 additions and 1 deletions
|
@ -44,8 +44,38 @@ namespace ana
|
|||
{
|
||||
namespace serializer
|
||||
{
|
||||
template <class T>
|
||||
struct template_is_container { enum { value = 0 }; };
|
||||
|
||||
// This could/should be done with Template Meta Programming
|
||||
template <class T>
|
||||
struct template_is_container< std::vector<T> > { enum { value = 1 }; };
|
||||
|
||||
template <class K, class D>
|
||||
struct template_is_container< std::vector<K,D> > { enum { value = 1 }; };
|
||||
|
||||
template <class T>
|
||||
struct template_is_container< std::list<T> > { enum { value = 1 }; };
|
||||
|
||||
template <class K, class D>
|
||||
struct template_is_container< std::list<K,D> > { enum { value = 1 }; };
|
||||
|
||||
template <class K, class D, class C>
|
||||
struct template_is_container< std::set<K,D,C> > { enum { value = 1 }; };
|
||||
|
||||
template <class K, class D>
|
||||
struct template_is_container< std::map<K,D> > { enum { value = 1 }; };
|
||||
|
||||
template <class K, class D>
|
||||
struct template_is_container< std::multimap<K,D> > { enum { value = 1 }; };
|
||||
|
||||
class bostream
|
||||
{
|
||||
private:
|
||||
template<class T, bool IsContainer> struct _inserter_helper;
|
||||
|
||||
template<class T, bool IsContainer> friend struct _inserter_helper;
|
||||
|
||||
public:
|
||||
bostream() :
|
||||
_s()
|
||||
|
@ -55,7 +85,7 @@ namespace ana
|
|||
template <class T>
|
||||
bostream& operator<< (T x)
|
||||
{
|
||||
_s.append(reinterpret_cast<char*>(&x), sizeof(T));
|
||||
_inserter_helper<T, template_is_container<T>::value >::call(this, x);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -100,6 +130,9 @@ namespace ana
|
|||
|
||||
class bistream
|
||||
{
|
||||
private:
|
||||
template<class T> friend class container_reader;
|
||||
|
||||
public:
|
||||
bistream(const std::string& str) :
|
||||
_s(str),
|
||||
|
@ -160,6 +193,112 @@ namespace ana
|
|||
std::string _s;
|
||||
std::size_t _pos;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
class container_writer
|
||||
{
|
||||
public:
|
||||
container_writer( size_t size, bostream& bos) :
|
||||
_elements_left( size ),
|
||||
_bos( bos )
|
||||
{
|
||||
_bos << uint32_t( size );
|
||||
}
|
||||
|
||||
container_writer& operator<<(T element)
|
||||
{
|
||||
assert( _elements_left > 0 );
|
||||
--_elements_left;
|
||||
|
||||
_bos << element;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
~container_writer()
|
||||
{
|
||||
if ( _elements_left != 0 )
|
||||
throw/* std::runtime_error*/("More elements were expected to be written.");
|
||||
}
|
||||
private:
|
||||
size_t _elements_left;
|
||||
bostream& _bos;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
class container_reader
|
||||
{
|
||||
public:
|
||||
container_reader( bistream& bis) :
|
||||
_elements_left( 0 ),
|
||||
_bis( bis )
|
||||
{
|
||||
_bis >> _elements_left;
|
||||
}
|
||||
|
||||
container_reader& operator>>(T& element)
|
||||
{
|
||||
assert( _elements_left > 0 );
|
||||
--_elements_left;
|
||||
|
||||
_bis >> element;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void skip(size_t elements = 1)
|
||||
{
|
||||
if ( elements > _elements_left )
|
||||
throw("Trying to skip too much.");
|
||||
|
||||
_elements_left -= elements;
|
||||
|
||||
_bis._pos += sizeof(T) * elements;
|
||||
|
||||
if ( _bis._pos > _bis._s.size() )
|
||||
throw("Too much mas skipped.");
|
||||
}
|
||||
|
||||
void finished()
|
||||
{
|
||||
skip( _elements_left );
|
||||
_elements_left = 0;
|
||||
}
|
||||
|
||||
~container_reader()
|
||||
{
|
||||
if ( _elements_left != 0 )
|
||||
finished();
|
||||
}
|
||||
|
||||
private:
|
||||
size_t _elements_left;
|
||||
bistream& _bis;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct bostream::_inserter_helper<T, false>
|
||||
{
|
||||
static void call(bostream* bos, const T& x)
|
||||
{
|
||||
bos->_s.append(reinterpret_cast<const char*>(&x), sizeof(T));
|
||||
}
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct bostream::_inserter_helper<T, true>
|
||||
{
|
||||
static void call(bostream* bos, const T& cont)
|
||||
{
|
||||
const uint32_t size(cont.size());
|
||||
(*bos) << size;
|
||||
|
||||
typename T::const_iterator it( cont.begin() );
|
||||
|
||||
for (; it != cont.end(); ++it)
|
||||
(*bos) << *it;
|
||||
}
|
||||
};
|
||||
} //serializer namespace
|
||||
} //ana namespace
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue