static variant update
This commit is contained in:
parent
fb27454cdf
commit
3f4a4468e0
3 changed files with 115 additions and 99 deletions
|
|
@ -168,6 +168,7 @@ set( fc_sources
|
||||||
src/variant.cpp
|
src/variant.cpp
|
||||||
src/exception.cpp
|
src/exception.cpp
|
||||||
src/variant_object.cpp
|
src/variant_object.cpp
|
||||||
|
src/static_variant.cpp
|
||||||
src/thread/thread.cpp
|
src/thread/thread.cpp
|
||||||
src/thread/thread_specific.cpp
|
src/thread/thread_specific.cpp
|
||||||
src/thread/future.cpp
|
src/thread/future.cpp
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
/** This source adapted from https://github.com/kmicklas/variadic-static_variant
|
|
||||||
|
/** This source adapted from https://github.com/kmicklas/variadic-static_variant Now available at https://github.com/kmicklas/variadic-variant.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2013 Kenneth Micklas
|
* Copyright (C) 2013 Kenneth Micklas
|
||||||
*
|
*
|
||||||
|
|
@ -13,21 +14,15 @@
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <typeinfo>
|
#include <typeinfo>
|
||||||
#include <fc/exception/exception.hpp>
|
#include <fc/exception/exception.hpp>
|
||||||
|
|
||||||
namespace fc {
|
namespace fc {
|
||||||
|
|
||||||
// Implementation details, the user should not import this:
|
// Implementation details, the user should not import this:
|
||||||
namespace impl {
|
namespace impl {
|
||||||
|
|
||||||
template<int N, typename... Ts>
|
template<int N, typename... Ts>
|
||||||
struct storage_ops;
|
struct storage_ops;
|
||||||
|
|
||||||
template<typename X, typename... Ts>
|
template<typename X, typename... Ts>
|
||||||
struct position;
|
struct position;
|
||||||
|
|
||||||
template<typename... Ts>
|
template<typename... Ts>
|
||||||
struct type_info;
|
struct type_info;
|
||||||
|
|
||||||
template<typename StaticVariant>
|
template<typename StaticVariant>
|
||||||
struct copy_construct
|
struct copy_construct
|
||||||
{
|
{
|
||||||
|
|
@ -40,7 +35,6 @@ struct copy_construct
|
||||||
sv.init(v);
|
sv.init(v);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename StaticVariant>
|
template<typename StaticVariant>
|
||||||
struct move_construct
|
struct move_construct
|
||||||
{
|
{
|
||||||
|
|
@ -53,25 +47,19 @@ struct move_construct
|
||||||
sv.init( std::move(v) );
|
sv.init( std::move(v) );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<int N, typename T, typename... Ts>
|
template<int N, typename T, typename... Ts>
|
||||||
struct storage_ops<N, T&, Ts...> {
|
struct storage_ops<N, T&, Ts...> {
|
||||||
static void del(int n, void *data) {}
|
static void del(int n, void *data) {}
|
||||||
static void con(int n, void *data) {}
|
static void con(int n, void *data) {}
|
||||||
|
|
||||||
template<typename visitor>
|
template<typename visitor>
|
||||||
static typename visitor::result_type apply(int n, void *data, visitor& v) {}
|
static typename visitor::result_type apply(int n, void *data, visitor& v) {}
|
||||||
|
|
||||||
template<typename visitor>
|
template<typename visitor>
|
||||||
static typename visitor::result_type apply(int n, void *data, const visitor& v) {}
|
static typename visitor::result_type apply(int n, void *data, const visitor& v) {}
|
||||||
|
|
||||||
template<typename visitor>
|
template<typename visitor>
|
||||||
static typename visitor::result_type apply(int n, const void *data, visitor& v) {}
|
static typename visitor::result_type apply(int n, const void *data, visitor& v) {}
|
||||||
|
|
||||||
template<typename visitor>
|
template<typename visitor>
|
||||||
static typename visitor::result_type apply(int n, const void *data, const visitor& v) {}
|
static typename visitor::result_type apply(int n, const void *data, const visitor& v) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<int N, typename T, typename... Ts>
|
template<int N, typename T, typename... Ts>
|
||||||
struct storage_ops<N, T, Ts...> {
|
struct storage_ops<N, T, Ts...> {
|
||||||
static void del(int n, void *data) {
|
static void del(int n, void *data) {
|
||||||
|
|
@ -82,32 +70,27 @@ struct storage_ops<N, T, Ts...> {
|
||||||
if(n == N) new(reinterpret_cast<T*>(data)) T();
|
if(n == N) new(reinterpret_cast<T*>(data)) T();
|
||||||
else storage_ops<N + 1, Ts...>::con(n, data);
|
else storage_ops<N + 1, Ts...>::con(n, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename visitor>
|
template<typename visitor>
|
||||||
static typename visitor::result_type apply(int n, void *data, visitor& v) {
|
static typename visitor::result_type apply(int n, void *data, visitor& v) {
|
||||||
if(n == N) return v(*reinterpret_cast<T*>(data));
|
if(n == N) return v(*reinterpret_cast<T*>(data));
|
||||||
else return storage_ops<N + 1, Ts...>::apply(n, data, v);
|
else return storage_ops<N + 1, Ts...>::apply(n, data, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename visitor>
|
template<typename visitor>
|
||||||
static typename visitor::result_type apply(int n, void *data, const visitor& v) {
|
static typename visitor::result_type apply(int n, void *data, const visitor& v) {
|
||||||
if(n == N) return v(*reinterpret_cast<T*>(data));
|
if(n == N) return v(*reinterpret_cast<T*>(data));
|
||||||
else return storage_ops<N + 1, Ts...>::apply(n, data, v);
|
else return storage_ops<N + 1, Ts...>::apply(n, data, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename visitor>
|
template<typename visitor>
|
||||||
static typename visitor::result_type apply(int n, const void *data, visitor& v) {
|
static typename visitor::result_type apply(int n, const void *data, visitor& v) {
|
||||||
if(n == N) return v(*reinterpret_cast<const T*>(data));
|
if(n == N) return v(*reinterpret_cast<const T*>(data));
|
||||||
else return storage_ops<N + 1, Ts...>::apply(n, data, v);
|
else return storage_ops<N + 1, Ts...>::apply(n, data, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename visitor>
|
template<typename visitor>
|
||||||
static typename visitor::result_type apply(int n, const void *data, const visitor& v) {
|
static typename visitor::result_type apply(int n, const void *data, const visitor& v) {
|
||||||
if(n == N) return v(*reinterpret_cast<const T*>(data));
|
if(n == N) return v(*reinterpret_cast<const T*>(data));
|
||||||
else return storage_ops<N + 1, Ts...>::apply(n, data, v);
|
else return storage_ops<N + 1, Ts...>::apply(n, data, v);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<int N>
|
template<int N>
|
||||||
struct storage_ops<N> {
|
struct storage_ops<N> {
|
||||||
static void del(int n, void *data) {
|
static void del(int n, void *data) {
|
||||||
|
|
@ -116,7 +99,6 @@ struct storage_ops<N> {
|
||||||
static void con(int n, void *data) {
|
static void con(int n, void *data) {
|
||||||
FC_THROW_EXCEPTION( fc::assert_exception, "Internal error: static_variant tag is invalid." );
|
FC_THROW_EXCEPTION( fc::assert_exception, "Internal error: static_variant tag is invalid." );
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename visitor>
|
template<typename visitor>
|
||||||
static typename visitor::result_type apply(int n, void *data, visitor& v) {
|
static typename visitor::result_type apply(int n, void *data, visitor& v) {
|
||||||
FC_THROW_EXCEPTION( fc::assert_exception, "Internal error: static_variant tag is invalid." );
|
FC_THROW_EXCEPTION( fc::assert_exception, "Internal error: static_variant tag is invalid." );
|
||||||
|
|
@ -134,22 +116,18 @@ struct storage_ops<N> {
|
||||||
FC_THROW_EXCEPTION( fc::assert_exception, "Internal error: static_variant tag is invalid." );
|
FC_THROW_EXCEPTION( fc::assert_exception, "Internal error: static_variant tag is invalid." );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename X>
|
template<typename X>
|
||||||
struct position<X> {
|
struct position<X> {
|
||||||
static const int pos = -1;
|
static const int pos = -1;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename X, typename... Ts>
|
template<typename X, typename... Ts>
|
||||||
struct position<X, X, Ts...> {
|
struct position<X, X, Ts...> {
|
||||||
static const int pos = 0;
|
static const int pos = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename X, typename T, typename... Ts>
|
template<typename X, typename T, typename... Ts>
|
||||||
struct position<X, T, Ts...> {
|
struct position<X, T, Ts...> {
|
||||||
static const int pos = position<X, Ts...>::pos != -1 ? position<X, Ts...>::pos + 1 : -1;
|
static const int pos = position<X, Ts...>::pos != -1 ? position<X, Ts...>::pos + 1 : -1;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T, typename... Ts>
|
template<typename T, typename... Ts>
|
||||||
struct type_info<T&, Ts...> {
|
struct type_info<T&, Ts...> {
|
||||||
static const bool no_reference_types = false;
|
static const bool no_reference_types = false;
|
||||||
|
|
@ -157,7 +135,6 @@ struct type_info<T&, Ts...> {
|
||||||
static const size_t size = type_info<Ts...>::size > sizeof(T&) ? type_info<Ts...>::size : sizeof(T&);
|
static const size_t size = type_info<Ts...>::size > sizeof(T&) ? type_info<Ts...>::size : sizeof(T&);
|
||||||
static const size_t count = 1 + type_info<Ts...>::count;
|
static const size_t count = 1 + type_info<Ts...>::count;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T, typename... Ts>
|
template<typename T, typename... Ts>
|
||||||
struct type_info<T, Ts...> {
|
struct type_info<T, Ts...> {
|
||||||
static const bool no_reference_types = type_info<Ts...>::no_reference_types;
|
static const bool no_reference_types = type_info<Ts...>::no_reference_types;
|
||||||
|
|
@ -165,7 +142,6 @@ struct type_info<T, Ts...> {
|
||||||
static const size_t size = type_info<Ts...>::size > sizeof(T) ? type_info<Ts...>::size : sizeof(T&);
|
static const size_t size = type_info<Ts...>::size > sizeof(T) ? type_info<Ts...>::size : sizeof(T&);
|
||||||
static const size_t count = 1 + type_info<Ts...>::count;
|
static const size_t count = 1 + type_info<Ts...>::count;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
struct type_info<> {
|
struct type_info<> {
|
||||||
static const bool no_reference_types = true;
|
static const bool no_reference_types = true;
|
||||||
|
|
@ -174,48 +150,94 @@ struct type_info<> {
|
||||||
static const size_t size = 0;
|
static const size_t size = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace impl
|
template<typename TTag>
|
||||||
|
size_t size( TTag )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename TTag, typename A, typename...Ts>
|
||||||
|
size_t size( TTag tag )
|
||||||
|
{
|
||||||
|
if (tag <= 0)
|
||||||
|
{
|
||||||
|
return sizeof(A);
|
||||||
|
}
|
||||||
|
|
||||||
|
return size<TTag, Ts...>( --tag );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class dynamic_storage
|
||||||
|
{
|
||||||
|
char* storage;
|
||||||
|
public:
|
||||||
|
dynamic_storage();
|
||||||
|
|
||||||
|
~dynamic_storage();
|
||||||
|
|
||||||
|
void* data() const;
|
||||||
|
|
||||||
|
void alloc( size_t size );
|
||||||
|
|
||||||
|
void release();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace impl
|
||||||
template<typename... Types>
|
template<typename... Types>
|
||||||
class static_variant {
|
class static_variant {
|
||||||
|
using tag_type = int64_t;
|
||||||
|
|
||||||
static_assert(impl::type_info<Types...>::no_reference_types, "Reference types are not permitted in static_variant.");
|
static_assert(impl::type_info<Types...>::no_reference_types, "Reference types are not permitted in static_variant.");
|
||||||
static_assert(impl::type_info<Types...>::no_duplicates, "static_variant type arguments contain duplicate types.");
|
static_assert(impl::type_info<Types...>::no_duplicates, "static_variant type arguments contain duplicate types.");
|
||||||
|
|
||||||
int _tag;
|
|
||||||
char storage[impl::type_info<Types...>::size];
|
|
||||||
|
|
||||||
template<typename X>
|
template<typename X>
|
||||||
|
using type_in_typelist = typename std::enable_if<impl::position<X, Types...>::pos != -1, X>::type; // type is in typelist of static_variant.
|
||||||
|
|
||||||
|
|
||||||
|
int _tag;
|
||||||
|
impl::dynamic_storage storage;
|
||||||
|
template<typename X, typename = type_in_typelist<X>>
|
||||||
void init(const X& x) {
|
void init(const X& x) {
|
||||||
_tag = impl::position<X, Types...>::pos;
|
_tag = impl::position<X, Types...>::pos;
|
||||||
new(storage) X(x);
|
storage.alloc( sizeof(X) );
|
||||||
|
new(storage.data()) X(x);
|
||||||
}
|
}
|
||||||
|
template<typename X, typename = type_in_typelist<X>>
|
||||||
template<typename X>
|
|
||||||
void init(X&& x) {
|
void init(X&& x) {
|
||||||
_tag = impl::position<X, Types...>::pos;
|
_tag = impl::position<X, Types...>::pos;
|
||||||
new(storage) X( std::move(x) );
|
storage.alloc( sizeof(X) );
|
||||||
|
new(storage.data()) X( std::move(x) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void init(tag_type tag)
|
||||||
|
{
|
||||||
|
FC_ASSERT( tag >= 0 );
|
||||||
|
FC_ASSERT( tag < count() );
|
||||||
|
_tag = tag;
|
||||||
|
storage.alloc( impl::size<tag_type, Types...>( tag ) );
|
||||||
|
impl::storage_ops<0, Types...>::con(_tag, storage.data());
|
||||||
|
}
|
||||||
|
|
||||||
|
void clean()
|
||||||
|
{
|
||||||
|
impl::storage_ops<0, Types...>::del(_tag, storage.data() );
|
||||||
|
storage.release();
|
||||||
|
}
|
||||||
template<typename StaticVariant>
|
template<typename StaticVariant>
|
||||||
friend struct impl::copy_construct;
|
friend struct impl::copy_construct;
|
||||||
template<typename StaticVariant>
|
template<typename StaticVariant>
|
||||||
friend struct impl::move_construct;
|
friend struct impl::move_construct;
|
||||||
public:
|
public:
|
||||||
template<typename X>
|
template<typename X, typename = type_in_typelist<X>>
|
||||||
struct tag
|
struct tag
|
||||||
{
|
{
|
||||||
static_assert(
|
|
||||||
impl::position<X, Types...>::pos != -1,
|
|
||||||
"Type not in static_variant."
|
|
||||||
);
|
|
||||||
static const int value = impl::position<X, Types...>::pos;
|
static const int value = impl::position<X, Types...>::pos;
|
||||||
};
|
};
|
||||||
static_variant()
|
static_variant()
|
||||||
{
|
{
|
||||||
_tag = 0;
|
init(0);
|
||||||
impl::storage_ops<0, Types...>::con(0, storage);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
template<typename... Other>
|
template<typename... Other>
|
||||||
static_variant( const static_variant<Other...>& cpy )
|
static_variant( const static_variant<Other...>& cpy )
|
||||||
{
|
{
|
||||||
|
|
@ -225,46 +247,34 @@ public:
|
||||||
{
|
{
|
||||||
cpy.visit( impl::copy_construct<static_variant>(*this) );
|
cpy.visit( impl::copy_construct<static_variant>(*this) );
|
||||||
}
|
}
|
||||||
|
|
||||||
static_variant( static_variant&& mv )
|
static_variant( static_variant&& mv )
|
||||||
{
|
{
|
||||||
mv.visit( impl::move_construct<static_variant>(*this) );
|
mv.visit( impl::move_construct<static_variant>(*this) );
|
||||||
}
|
}
|
||||||
|
template<typename X, typename = type_in_typelist<X>>
|
||||||
template<typename X>
|
|
||||||
static_variant(const X& v) {
|
static_variant(const X& v) {
|
||||||
static_assert(
|
|
||||||
impl::position<X, Types...>::pos != -1,
|
|
||||||
"Type not in static_variant."
|
|
||||||
);
|
|
||||||
init(v);
|
init(v);
|
||||||
}
|
}
|
||||||
~static_variant() {
|
~static_variant() {
|
||||||
impl::storage_ops<0, Types...>::del(_tag, storage);
|
clean();
|
||||||
}
|
}
|
||||||
|
template<typename X, typename = type_in_typelist<X>>
|
||||||
|
|
||||||
template<typename X>
|
|
||||||
static_variant& operator=(const X& v) {
|
static_variant& operator=(const X& v) {
|
||||||
static_assert(
|
clean();
|
||||||
impl::position<X, Types...>::pos != -1,
|
|
||||||
"Type not in static_variant."
|
|
||||||
);
|
|
||||||
this->~static_variant();
|
|
||||||
init(v);
|
init(v);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
static_variant& operator=( const static_variant& v )
|
static_variant& operator=( const static_variant& v )
|
||||||
{
|
{
|
||||||
if( this == &v ) return *this;
|
if( this == &v ) return *this;
|
||||||
this->~static_variant();
|
clean();
|
||||||
v.visit( impl::copy_construct<static_variant>(*this) );
|
v.visit( impl::copy_construct<static_variant>(*this) );
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
static_variant& operator=( static_variant&& v )
|
static_variant& operator=( static_variant&& v )
|
||||||
{
|
{
|
||||||
if( this == &v ) return *this;
|
if( this == &v ) return *this;
|
||||||
this->~static_variant();
|
clean();
|
||||||
v.visit( impl::move_construct<static_variant>(*this) );
|
v.visit( impl::move_construct<static_variant>(*this) );
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
@ -276,98 +286,73 @@ public:
|
||||||
{
|
{
|
||||||
return a.which() < b.which();
|
return a.which() < b.which();
|
||||||
}
|
}
|
||||||
|
template<typename X, typename = type_in_typelist<X>>
|
||||||
template<typename X>
|
|
||||||
X& get() {
|
X& get() {
|
||||||
static_assert(
|
|
||||||
impl::position<X, Types...>::pos != -1,
|
|
||||||
"Type not in static_variant."
|
|
||||||
);
|
|
||||||
if(_tag == impl::position<X, Types...>::pos) {
|
if(_tag == impl::position<X, Types...>::pos) {
|
||||||
void* tmp(storage);
|
return *reinterpret_cast<X*>(storage.data());
|
||||||
return *reinterpret_cast<X*>(tmp);
|
|
||||||
} else {
|
} else {
|
||||||
FC_THROW_EXCEPTION( fc::assert_exception, "static_variant does not contain a value of type ${t}", ("t",fc::get_typename<X>::name()) );
|
FC_THROW_EXCEPTION( fc::assert_exception, "static_variant does not contain a value of type ${t}", ("t",fc::get_typename<X>::name()) );
|
||||||
// std::string("static_variant does not contain value of type ") + typeid(X).name()
|
|
||||||
// );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
template<typename X>
|
template<typename X, typename = type_in_typelist<X>>
|
||||||
const X& get() const {
|
const X& get() const {
|
||||||
static_assert(
|
|
||||||
impl::position<X, Types...>::pos != -1,
|
|
||||||
"Type not in static_variant."
|
|
||||||
);
|
|
||||||
if(_tag == impl::position<X, Types...>::pos) {
|
if(_tag == impl::position<X, Types...>::pos) {
|
||||||
const void* tmp(storage);
|
return *reinterpret_cast<const X*>(storage.data());
|
||||||
return *reinterpret_cast<const X*>(tmp);
|
|
||||||
} else {
|
} else {
|
||||||
FC_THROW_EXCEPTION( fc::assert_exception, "static_variant does not contain a value of type ${t}", ("t",fc::get_typename<X>::name()) );
|
FC_THROW_EXCEPTION( fc::assert_exception, "static_variant does not contain a value of type ${t}", ("t",fc::get_typename<X>::name()) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
template<typename visitor>
|
template<typename visitor>
|
||||||
typename visitor::result_type visit(visitor& v) {
|
typename visitor::result_type visit(visitor& v) {
|
||||||
return impl::storage_ops<0, Types...>::apply(_tag, storage, v);
|
return impl::storage_ops<0, Types...>::apply(_tag, storage.data(), v);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename visitor>
|
template<typename visitor>
|
||||||
typename visitor::result_type visit(const visitor& v) {
|
typename visitor::result_type visit(const visitor& v) {
|
||||||
return impl::storage_ops<0, Types...>::apply(_tag, storage, v);
|
return impl::storage_ops<0, Types...>::apply(_tag, storage.data(), v);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename visitor>
|
template<typename visitor>
|
||||||
typename visitor::result_type visit(visitor& v)const {
|
typename visitor::result_type visit(visitor& v)const {
|
||||||
return impl::storage_ops<0, Types...>::apply(_tag, storage, v);
|
return impl::storage_ops<0, Types...>::apply(_tag, storage.data(), v);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename visitor>
|
template<typename visitor>
|
||||||
typename visitor::result_type visit(const visitor& v)const {
|
typename visitor::result_type visit(const visitor& v)const {
|
||||||
return impl::storage_ops<0, Types...>::apply(_tag, storage, v);
|
return impl::storage_ops<0, Types...>::apply(_tag, storage.data(), v);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int count() { return impl::type_info<Types...>::count; }
|
static int count() { return impl::type_info<Types...>::count; }
|
||||||
void set_which( int w ) {
|
void set_which( int w ) {
|
||||||
|
FC_ASSERT( w >= 0 );
|
||||||
FC_ASSERT( w < count() );
|
FC_ASSERT( w < count() );
|
||||||
this->~static_variant();
|
clean();
|
||||||
_tag = w;
|
init(w);
|
||||||
impl::storage_ops<0, Types...>::con(_tag, storage);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int which() const {return _tag;}
|
int which() const {return _tag;}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Result>
|
template<typename Result>
|
||||||
struct visitor {
|
struct visitor {
|
||||||
typedef Result result_type;
|
typedef Result result_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct from_static_variant
|
struct from_static_variant
|
||||||
{
|
{
|
||||||
variant& var;
|
variant& var;
|
||||||
const uint32_t _max_depth;
|
const uint32_t _max_depth;
|
||||||
from_static_variant( variant& dv, uint32_t max_depth ):var(dv),_max_depth(max_depth){}
|
from_static_variant( variant& dv, uint32_t max_depth ):var(dv),_max_depth(max_depth){}
|
||||||
|
|
||||||
typedef void result_type;
|
typedef void result_type;
|
||||||
template<typename T> void operator()( const T& v )const
|
template<typename T> void operator()( const T& v )const
|
||||||
{
|
{
|
||||||
to_variant( v, var, _max_depth );
|
to_variant( v, var, _max_depth );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct to_static_variant
|
struct to_static_variant
|
||||||
{
|
{
|
||||||
const variant& var;
|
const variant& var;
|
||||||
const uint32_t _max_depth;
|
const uint32_t _max_depth;
|
||||||
to_static_variant( const variant& dv, uint32_t max_depth ):var(dv),_max_depth(max_depth){}
|
to_static_variant( const variant& dv, uint32_t max_depth ):var(dv),_max_depth(max_depth){}
|
||||||
|
|
||||||
typedef void result_type;
|
typedef void result_type;
|
||||||
template<typename T> void operator()( T& v )const
|
template<typename T> void operator()( T& v )const
|
||||||
{
|
{
|
||||||
from_variant( var, v, _max_depth );
|
from_variant( var, v, _max_depth );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
template<typename... T> void to_variant( const fc::static_variant<T...>& s, fc::variant& v, uint32_t max_depth )
|
template<typename... T> void to_variant( const fc::static_variant<T...>& s, fc::variant& v, uint32_t max_depth )
|
||||||
{
|
{
|
||||||
FC_ASSERT( max_depth > 0 );
|
FC_ASSERT( max_depth > 0 );
|
||||||
|
|
@ -384,6 +369,5 @@ struct visitor {
|
||||||
s.set_which( ar[0].as_uint64() );
|
s.set_which( ar[0].as_uint64() );
|
||||||
s.visit( to_static_variant(ar[1], max_depth - 1) );
|
s.visit( to_static_variant(ar[1], max_depth - 1) );
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename... T> struct get_typename { static const char* name() { return typeid(static_variant<T...>).name(); } };
|
template<typename... T> struct get_typename { static const char* name() { return typeid(static_variant<T...>).name(); } };
|
||||||
} // namespace fc
|
} // namespace fc
|
||||||
31
src/static_variant.cpp
Normal file
31
src/static_variant.cpp
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
#include <fc/static_variant.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
namespace fc { namespace impl {
|
||||||
|
|
||||||
|
dynamic_storage::dynamic_storage() : storage(nullptr) {};
|
||||||
|
|
||||||
|
dynamic_storage::~dynamic_storage()
|
||||||
|
{
|
||||||
|
release();
|
||||||
|
}
|
||||||
|
|
||||||
|
void* dynamic_storage::data() const
|
||||||
|
{
|
||||||
|
FC_ASSERT( storage != nullptr );
|
||||||
|
return (void*)storage;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dynamic_storage::alloc( size_t size )
|
||||||
|
{
|
||||||
|
release();
|
||||||
|
storage = new char[size];
|
||||||
|
}
|
||||||
|
|
||||||
|
void dynamic_storage::release()
|
||||||
|
{
|
||||||
|
delete [] storage;
|
||||||
|
storage = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
}}
|
||||||
Loading…
Reference in a new issue