13 #ifndef GIL_DYNAMICIMAGE_VARIANT_HPP
14 #define GIL_DYNAMICIMAGE_VARIANT_HPP
25 #include "../../gil_config.hpp"
26 #include "../../utilities.hpp"
31 #include <boost/bind.hpp>
32 #include <boost/utility/enable_if.hpp>
33 #include <boost/mpl/bool.hpp>
34 #include <boost/mpl/transform.hpp>
35 #include <boost/mpl/size.hpp>
36 #include <boost/mpl/sizeof.hpp>
37 #include <boost/mpl/max.hpp>
38 #include <boost/mpl/at.hpp>
39 #include <boost/mpl/fold.hpp>
41 namespace boost {
namespace gil {
44 template <
typename Types,
typename T>
struct type_to_index;
45 template <
typename Op,
typename T>
struct reduce;
46 struct destructor_op {
47 typedef void result_type;
48 template <
typename T> result_type operator()(
const T& t)
const { t.~T(); }
50 template <
typename T,
typename Bits>
void copy_construct_in_place(
const T& t, Bits& bits);
51 template <
typename Bits>
struct copy_construct_in_place_fn;
52 template <
typename Types>
struct type_to_index_fn;
88 template <
typename Types>
91 static const std::size_t MAX_SIZE = mpl::fold<Types, mpl::size_t<0>, mpl::max<mpl::_1, mpl::sizeof_<mpl::_2> > >::type::value;
92 static const std::size_t NUM_TYPES = mpl::size<Types>::value;
94 typedef Types types_t;
96 typedef struct {
char data[MAX_SIZE]; } base_t;
99 variant() : _index(0) {
new(&_bits)
typename mpl::at_c<Types,0>::type(); }
100 virtual ~
variant() { apply_operation(*
this, detail::destructor_op()); }
103 template <
typename T>
explicit variant(
const T& obj){ _index=type_id<T>();
if (_index==NUM_TYPES)
throw std::bad_cast(); detail::copy_construct_in_place(obj, _bits); }
105 template <
typename Types2>
explicit variant(
const variant<Types2>& obj) : _index(apply_operation(obj,detail::type_to_index_fn<Types>())) {
106 if (_index==NUM_TYPES)
throw std::bad_cast();
107 apply_operation(obj, detail::copy_construct_in_place_fn<base_t>(_bits));
111 template <
typename T>
explicit variant(T& obj,
bool do_swap);
113 template <
typename T>
variant& operator=(
const T& obj) {
variant tmp(obj); swap(*
this,tmp);
return *
this; }
116 variant(
const variant& v) : _index(v._index) { apply_operation(v, detail::copy_construct_in_place_fn<base_t>(_bits)); }
117 template <
typename T>
void move_in(T& obj) {
variant tmp(obj,
true); swap(*
this,tmp); }
122 template <
typename T>
static bool has_type() {
return type_id<T>()!=NUM_TYPES; }
124 template <
typename T>
const T& _dynamic_cast()
const {
if (!current_type_is<T>())
throw std::bad_cast();
return *gil_reinterpret_cast_c<const T*>(&_bits); }
125 template <
typename T> T& _dynamic_cast() {
if (!current_type_is<T>())
throw std::bad_cast();
return *gil_reinterpret_cast < T*>(&_bits); }
127 template <
typename T>
bool current_type_is()
const {
return type_id<T>()==_index; }
129 base_t bits()
const {
return _bits; }
130 std::size_t index()
const {
return _index; }
136 template <
typename Types2,
typename UnaryOp>
friend typename UnaryOp::result_type apply_operation(
variant<Types2>& var, UnaryOp op);
137 template <
typename Types2,
typename UnaryOp>
friend typename UnaryOp::result_type apply_operation(
const variant<Types2>& var, UnaryOp op);
138 template <
typename Types1,
typename Types2,
typename BinaryOp>
friend typename BinaryOp::result_type apply_operation(
const variant<Types1>& arg1,
const variant<Types2>& arg2, BinaryOp op);
146 template <
typename T,
typename Bits>
147 void copy_construct_in_place(
const T& t, Bits& bits) {
148 T& b=*gil_reinterpret_cast<T*>(&bits);
152 template <
typename Bits>
153 struct copy_construct_in_place_fn {
154 typedef void result_type;
156 copy_construct_in_place_fn(Bits& dst) : _dst(dst) {}
158 template <
typename T>
void operator()(
const T& src)
const { copy_construct_in_place(src,_dst); }
161 template <
typename Bits>
164 equal_to_fn(
const Bits& dst) : _dst(dst) {}
166 typedef bool result_type;
167 template <
typename T> result_type operator()(
const T& x)
const {
168 return x==*gil_reinterpret_cast_c<const T*>(&_dst);
172 template <
typename Types>
173 struct type_to_index_fn {
174 typedef std::size_t result_type;
176 template <
typename T> result_type operator()(
const T&)
const {
return detail::type_to_index<Types,T>::value; }
181 template <
typename Types>
182 template <
typename T> variant<Types>::variant(T& obj,
bool do_swap) {
184 if (_index==NUM_TYPES)
throw std::bad_cast();
188 swap(obj, *gil_reinterpret_cast<T*>(&_bits));
190 detail::copy_construct_in_place(const_cast<const T&>(obj), _bits);
193 template <
typename Types>
194 void swap(variant<Types>& x, variant<Types>& y) {
199 template <
typename Types>
200 inline bool operator==(
const variant<Types>& x,
const variant<Types>& y) {
201 return x._index==y._index &&
apply_operation(x,detail::equal_to_fn<
typename variant<Types>::base_t>(y._bits));
204 template <
typename C>
205 inline bool operator!=(
const variant<C>& x,
const variant<C>& y) {
BOOST_FORCEINLINE UnaryOp::result_type apply_operation(variant< Types > &arg, UnaryOp op)
Invokes a generic mutable operation (represented as a unary function object) on a variant...
Definition: apply_operation.hpp:35
Represents a concrete instance of a run-time specified type from a set of typesA concept is typically...
Definition: variant.hpp:89
void swap(const boost::gil::planar_pixel_reference< CR, CS > x, const boost::gil::planar_pixel_reference< CR, CS > y)
swap for planar_pixel_reference
Definition: planar_pixel_reference.hpp:193
Returns the index corresponding to the first occurrance of a given given type in. ...
Definition: utilities.hpp:307