peerplays-fc/include/fc/interprocess/container.hpp

136 lines
4.5 KiB
C++
Raw Normal View History

#pragma once
#include <fc/variant.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/interprocess/containers/string.hpp>
#include <boost/interprocess/containers/vector.hpp>
#include <boost/interprocess/containers/map.hpp>
#include <boost/interprocess/containers/flat_map.hpp>
2016-10-20 18:32:11 +00:00
#include <boost/interprocess/containers/set.hpp>
#include <boost/interprocess/containers/deque.hpp>
#include <fc/crypto/hex.hpp>
#include <fc/exception/exception.hpp>
2016-09-28 19:55:08 +00:00
#include <fc/io/raw_fwd.hpp>
namespace fc {
namespace bip = boost::interprocess;
template<typename... T >
void to_variant( const bip::deque< T... >& t, fc::variant& v, uint32_t max_depth ) {
FC_ASSERT( max_depth > 0, "Recursion depth exceeded!" );
--max_depth;
std::vector<variant> vars(t.size());
for( size_t i = 0; i < t.size(); ++i ) {
to_variant( t[i], vars[i], max_depth );
}
v = std::move(vars);
}
template<typename T, typename... A>
void from_variant( const fc::variant& v, bip::deque< T, A... >& d, uint32_t max_depth ) {
FC_ASSERT( max_depth > 0, "Recursion depth exceeded!" );
--max_depth;
const variants& vars = v.get_array();
d.clear();
d.resize( vars.size() );
for( uint32_t i = 0; i < vars.size(); ++i ) {
from_variant( vars[i], d[i], max_depth );
}
}
template<typename K, typename V, typename... T >
void to_variant( const bip::map< K, V, T... >& var, fc::variant& vo, uint32_t max_depth ) {
FC_ASSERT( max_depth > 0, "Recursion depth exceeded!" );
--max_depth;
std::vector< variant > vars(var.size());
size_t i = 0;
for( auto itr = var.begin(); itr != var.end(); ++itr, ++i )
vars[i] = fc::variant( *itr, max_depth );
vo = vars;
}
template<typename... T >
void to_variant( const bip::vector< T... >& t, fc::variant& v, uint32_t max_depth ) {
FC_ASSERT( max_depth > 0, "Recursion depth exceeded!" );
--max_depth;
std::vector<variant> vars(t.size());
for( size_t i = 0; i < t.size(); ++i ) {
to_variant( t[i], vars[i], max_depth );
}
v = std::move(vars);
}
template<typename T, typename... A>
void from_variant( const fc::variant& v, bip::vector< T, A... >& d, uint32_t max_depth ) {
FC_ASSERT( max_depth > 0, "Recursion depth exceeded!" );
--max_depth;
const variants& vars = v.get_array();
d.clear();
d.resize( vars.size() );
for( uint32_t i = 0; i < vars.size(); ++i ) {
from_variant( vars[i], d[i], max_depth );
}
}
2016-09-28 19:55:08 +00:00
2016-10-20 18:32:11 +00:00
template<typename... T >
void to_variant( const bip::set< T... >& t, fc::variant& v, uint32_t max_depth ) {
FC_ASSERT( max_depth > 0, "Recursion depth exceeded!" );
--max_depth;
2016-10-20 18:32:11 +00:00
std::vector<variant> vars;
vars.reserve(t.size());
for( const auto& item : t ) {
vars.emplace_back( variant( item, max_depth ) );
2016-10-20 18:32:11 +00:00
}
v = std::move(vars);
}
template<typename... A>
void to_variant( const bip::vector<char, A...>& t, fc::variant& v, uint32_t max_depth = 1 )
{
if( t.size() )
v = variant(fc::to_hex(t.data(), t.size()));
else
v = "";
}
template<typename... A>
void from_variant( const fc::variant& v, bip::vector<char, A...>& d, uint32_t max_depth = 1 )
{
auto str = v.as_string();
d.resize( str.size() / 2 );
if( d.size() )
{
size_t r = fc::from_hex( str, d.data(), d.size() );
FC_ASSERT( r == d.size() );
}
}
2016-09-28 19:55:08 +00:00
namespace raw {
namespace bip = boost::interprocess;
template<typename Stream, typename T, typename... A>
inline void pack( Stream& s, const bip::vector<T,A...>& value, uint32_t _max_depth=FC_PACK_MAX_DEPTH ) {
FC_ASSERT( _max_depth > 0 );
--_max_depth;
pack( s, unsigned_int((uint32_t)value.size()), _max_depth );
auto itr = value.begin();
auto end = value.end();
while( itr != end ) {
fc::raw::pack( s, *itr, _max_depth );
++itr;
}
2016-09-28 19:55:08 +00:00
}
template<typename Stream, typename T, typename... A>
inline void unpack( Stream& s, bip::vector<T,A...>& value, uint32_t _max_depth=FC_PACK_MAX_DEPTH ) {
FC_ASSERT( _max_depth > 0 );
--_max_depth;
unsigned_int size;
unpack( s, size, _max_depth );
value.clear(); value.resize(size);
for( auto& item : value )
fc::raw::unpack( s, item, _max_depth );
2016-09-28 19:55:08 +00:00
}
}
}