Generic Image Library: variant.hpp Source File Boost , ,
variant.hpp Go to the documentation of this file. 00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef GIL_DYNAMICIMAGE_VARIANT_HPP
00014 #define GIL_DYNAMICIMAGE_VARIANT_HPP
00015
00024
00025 #include "../../gil_config.hpp"
00026 #include "../../utilities.hpp"
00027 #include <cstddef>
00028 #include <cassert>
00029 #include <algorithm>
00030 #include <typeinfo>
00031 #include <boost/bind.hpp>
00032
00033 #include <boost/mpl/transform.hpp>
00034 #include <boost/mpl/size.hpp>
00035 #include <boost/mpl/sizeof.hpp>
00036 #include <boost/mpl/max.hpp>
00037 #include <boost/mpl/at.hpp>
00038 #include <boost/mpl/fold.hpp>
00039
00040 namespace boost { namespace gil {
00041
00042 namespace detail {
00043 template <typename Types, typename T> struct type_to_index;
00044 template <typename Op, typename T> struct reduce;
00045 struct destructor_op {
00046 typedef void result_type;
00047 template <typename T> result_type operator()(const T& t) const { t.~T(); }
00048 };
00049 template <typename T, typename Bits> void copy_construct_in_place(const T& t, Bits& bits);
00050 template <typename Bits> struct copy_construct_in_place_fn;
00051 }
00086 template <typename Types>
00087 class variant {
00088
00089 static const std::size_t MAX_SIZE = mpl::fold<Types, mpl::size_t<0>, mpl::max<mpl::_1, mpl::sizeof_<mpl::_2> > >::type::value;
00090 static const std::size_t NUM_TYPES = mpl::size<Types>::value;
00091 public :
00092 typedef Types types_t;
00093
00094 typedef struct { char data[MAX_SIZE]; } base_t;
00095
00096
00097 variant () : _index(0) { new (&_bits) typename mpl::at_c<Types,0>::type(); }
00098 virtual ~variant () { apply_operation(*this , detail::destructor_op()); }
00099
00100
00101 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); }
00102
00103
00104 template <typename T> explicit variant (T& obj, bool do_swap);
00105
00106 template <typename T> variant & operator=(const T& obj) { variant tmp(obj); swap(*this ,tmp); return *this ; }
00107 variant & operator=(const variant & v) { variant tmp(v ); swap(*this ,tmp); return *this ; }
00108
00109 variant (const variant & v) : _index(v._index ) { apply_operation(v, detail::copy_construct_in_place_fn<base_t>(_bits)); }
00110 template <typename T> void move_in(T& obj) { variant tmp(obj, true ); swap(*this ,tmp); }
00111
00112 template <typename TS> friend bool operator==(const variant<TS> & x, const variant<TS> & y);
00113 template <typename TS> friend bool operator!=(const variant<TS> & x, const variant<TS> & y);
00114
00115 template <typename T> static bool has_type() { return type_id<T>()!=NUM_TYPES; }
00116
00117 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); }
00118 template <typename T> T& _dynamic_cast() { if (!current_type_is<T>()) throw std::bad_cast(); return *gil_reinterpret_cast < T*>(&_bits); }
00119
00120 template <typename T> bool current_type_is() const { return type_id<T>()==_index; }
00121
00122 private :
00123 template <typename T> static std::size_t type_id() { return detail::type_to_index<Types,T>::value ; }
00124
00125 template <typename Cs> friend void swap(variant<Cs> & x, variant<Cs> & y);
00126 template <typename Types2, typename UnaryOp> friend typename UnaryOp::result_type apply_operation(variant<Types2> & var, UnaryOp op);
00127 template <typename Types2, typename UnaryOp> friend typename UnaryOp::result_type apply_operation(const variant<Types2> & var, UnaryOp op);
00128 template <typename Types1, typename Types2, typename BinaryOp> friend typename BinaryOp::result_type apply_operation(const variant<Types1> & arg1, const variant<Types2> & arg2, BinaryOp op);
00129
00130 base_t _bits;
00131 std::size_t _index;
00132 };
00133
00134 namespace detail {
00135
00136 template <typename T, typename Bits>
00137 void copy_construct_in_place(const T& t, Bits& bits) {
00138 T& b=*gil_reinterpret_cast<T*>(&bits);
00139 new (&b)T(t);
00140 }
00141
00142 template <typename Bits>
00143 struct copy_construct_in_place_fn {
00144 typedef void result_type;
00145 Bits& _dst;
00146 copy_construct_in_place_fn(Bits& dst) : _dst(dst) {}
00147
00148 template <typename T> void operator()(const T& src) const { copy_construct_in_place(src,_dst); }
00149 };
00150
00151 template <typename Bits>
00152 struct equal_to_fn {
00153 const Bits& _dst;
00154 equal_to_fn(const Bits& dst) : _dst(dst) {}
00155
00156 typedef bool result_type;
00157 template <typename T> result_type operator()(const T& x) const {
00158 return x==*gil_reinterpret_cast_c<const T*>(&_dst);
00159 }
00160 };
00161 }
00162
00163
00164 template <typename Types>
00165 template <typename T> variant<Types>::variant(T& obj, bool do_swap) {
00166 _index=type_id<T>();
00167 if (_index==NUM_TYPES) throw std::bad_cast();
00168
00169 if (do_swap) {
00170 new (&_bits) T();
00171 swap(obj, *gil_reinterpret_cast<T*>(&_bits));
00172 } else
00173 detail::copy_construct_in_place(const_cast<const T&>(obj), _bits);
00174 }
00175
00176 template <typename Types>
00177 void swap(variant<Types>& x, variant<Types>& y) {
00178 std::swap(x._bits,y._bits);
00179 std::swap(x._index, y._index);
00180 }
00181
00182 template <typename Types>
00183 inline bool operator==(const variant<Types>& x, const variant<Types>& y) {
00184 return x._index==y._index && apply_operation (x,detail::equal_to_fn<typename variant<Types>::base_t>(y._bits));
00185 }
00186
00187 template <typename C>
00188 inline bool operator!=(const variant<C>& x, const variant<C>& y) {
00189 return !(x==y);
00190 }
00191
00192 } }
00193
00194 #endif
Generated on Sat May 2 13:50:15 2009 for Generic Image Library by
1.5.6
Статья Generic Image Library: variant.hpp Source File раздела может быть полезна для разработчиков на c++ и boost.
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.
:: Главная :: ::