00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #ifndef MORE_GENERIC_H
00031 #define MORE_GENERIC_H
00032
00033 #include <utility>
00034 #include <iterator>
00035 #include <new>
00036 #include <memory>
00037
00038 namespace more {
00039 namespace gen {
00040
00041 class generic;
00042
00043
00044
00045
00046 namespace bits_generic {
00047
00048 struct vt_type
00049 {
00050 void (*construct_copy)(generic* dest, generic const& src);
00051 void (*destruct)(generic* dest);
00052 };
00053
00054 template<typename T>
00055 struct scalar_vt
00056 {
00057 static void
00058 construct_copy(generic* obj, generic const& src)
00059 {
00060 if (sizeof(T) <= sizeof(void*))
00061 new(&reinterpret_cast<T&>(obj->p))
00062 T(reinterpret_cast<T const&>(src.p));
00063 else
00064 obj->p = new T(*static_cast<T const*>(src.p));
00065 }
00066
00067 static void
00068 destruct(generic* obj)
00069 {
00070 if (sizeof(T) <= sizeof(void*))
00071 reinterpret_cast<T&>(obj->p).~T();
00072 else
00073 delete static_cast<T*>(obj->p);
00074 }
00075
00076 static vt_type et;
00077 };
00078
00079 template<>
00080 struct scalar_vt<void>
00081 {
00082 static void construct_copy(generic* obj, generic const& src) {}
00083 static void destruct(generic* obj) {}
00084 static vt_type et;
00085 };
00086
00087 template<typename T>
00088 struct vector_vt
00089 {
00090 struct layout {
00091 T* end;
00092 T x[1];
00093 };
00094 static T* begin(generic* x) {
00095 return static_cast<layout*>(x->p)->x;
00096 }
00097 static T* end(generic* x) {
00098 return static_cast<layout*>(x->p)->end;
00099 }
00100 static T const* begin(generic const* x) {
00101 return static_cast<layout const*>(x->p)->x;
00102 }
00103 static T const* end(generic const* x) {
00104 return static_cast<layout const*>(x->p)->end;
00105 }
00106 template<typename InputIterator>
00107 static void
00108 construct(generic* obj,
00109 InputIterator first, InputIterator last) {
00110 std::size_t n = std::distance(first, last);
00111 layout* p = static_cast<layout*>
00112 (::operator new(sizeof(layout) + sizeof(T)*(n-1)));
00113 p->end = p->x + n;
00114 obj->p = p;
00115 std::uninitialized_copy(first, last, p->x);
00116 }
00117 static void
00118 construct_copy(generic* obj, generic const& src) {
00119 T const* first = begin(&src);
00120 T const* last = end(&src);
00121 std::size_t n = last - first;
00122 layout* p = static_cast<layout*>
00123 (::operator new(sizeof(layout) + sizeof(T)*(n-1)));
00124 p->end = p->x + n;
00125 obj->p = p;
00126 std::uninitialized_copy(first, last, p->x);
00127 }
00128 static void
00129 destruct(generic* obj) {
00130 T* first = begin(obj);
00131 T* last = end(obj);
00132 while (first != last) {
00133 first->~T();
00134 ++first;
00135 }
00136 ::operator delete(obj->p);
00137 }
00138 static vt_type et;
00139 };
00140
00141 template<typename T>
00142 vt_type scalar_vt<T>::et = { construct_copy, destruct };
00143 template<typename T>
00144 vt_type vector_vt<T>::et = { construct_copy, destruct };
00145
00146 }
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157 struct generic
00158 {
00159 generic()
00160 : m_vt(&bits_generic::scalar_vt<void>::et) {}
00161
00162 generic(generic const& x)
00163 : m_vt(x.m_vt) { m_vt->construct_copy(this, x); }
00164
00165 ~generic() { m_vt->destruct(this); }
00166
00167 generic& operator=(generic const& rhs)
00168 {
00169 this->~generic();
00170 new(this) generic(rhs);
00171 return *this;
00172 }
00173
00174 template<typename T>
00175 generic(T const& x)
00176 {
00177 m_vt = &bits_generic::scalar_vt<T>::et;
00178 if (sizeof(T) <= sizeof(void*))
00179 new(&reinterpret_cast<T&>(p)) T(x);
00180 else
00181 p = new T(x);
00182 }
00183
00184 template<typename InputIterator>
00185 generic(InputIterator first, InputIterator last)
00186 {
00187 typedef typename std::iterator_traits<InputIterator>::value_type
00188 value_type;
00189 m_vt = &bits_generic::vector_vt<value_type>::et;
00190 bits_generic::vector_vt<value_type>::construct(this, first, last);
00191 }
00192
00193 template<typename T>
00194 bool is()
00195 {
00196 return m_vt == &bits_generic::scalar_vt<T>::et;
00197 }
00198
00199 template<typename T>
00200 T&
00201 to()
00202 {
00203 if (sizeof(T) <= sizeof(void*))
00204 return reinterpret_cast<T&>(p);
00205 else
00206 return *static_cast<T*>(p);
00207 }
00208
00209 template<typename T>
00210 T const&
00211 to() const
00212 {
00213 if (sizeof(T) <= sizeof(void*))
00214 return reinterpret_cast<T const&>(p);
00215 else
00216 return *static_cast<T const*>(p);
00217 }
00218
00219 template<typename T>
00220 std::pair<T*, T*>
00221 to_range()
00222 {
00223 return std::pair<T*, T*>(bits_generic::vector_vt<T>::begin(this),
00224 bits_generic::vector_vt<T>::end(this));
00225 }
00226
00227 template<typename T>
00228 std::pair<T const*, T const*>
00229 to_range() const
00230 {
00231 return std::pair<T const*, T const*>(
00232 bits_generic::vector_vt<T>::begin(this),
00233 bits_generic::vector_vt<T>::end(this));
00234 }
00235
00236 private:
00237 bits_generic::vt_type* m_vt;
00238 void* p;
00239
00240 template<typename T> friend class bits_generic::scalar_vt;
00241 template<typename T> friend class bits_generic::vector_vt;
00242 };
00243
00244 }}
00245
00246 #endif