value_store.h
Go to the documentation of this file.
00001 //
00002 //  Copyright (c) Benjamin Kaufmann 2010
00003 //
00004 //  This is free software; you can redistribute it and/or modify
00005 //  it under the terms of the GNU General Public License as published by
00006 //  the Free Software Foundation; either version 2 of the License, or
00007 //  (at your option) any later version. 
00008 // 
00009 //  This file is distributed in the hope that it will be useful,
00010 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 //  GNU General Public License for more details.
00013 //
00014 //  You should have received a copy of the GNU General Public License
00015 //  along with this file; if not, write to the Free Software
00016 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017 //
00018 //
00019 // NOTE: ProgramOptions is inspired by Boost.Program_options
00020 //       see: www.boost.org/libs/program_options
00021 //
00022 #ifndef PROGRAM_OPTIONS_VALUE_STORE_H_INCLUDED
00023 #define PROGRAM_OPTIONS_VALUE_STORE_H_INCLUDED
00024 #include <typeinfo>
00025 #include <new>
00026 namespace ProgramOptions { 
00027 namespace detail {
00028 typedef void (*vcall_type)(const void* in, void** out);
00029 typedef vcall_type vtable_type[4];
00030 typedef vtable_type* vptr_type;
00031 // workaround: some compilers don't support
00032 // out-of-class definition of member templates.
00033 template <class T>
00034 inline vptr_type vtable(const T* = 0);
00035 template <class T>
00036 inline vptr_type base_vtable(const T* = 0);
00037 }
00038 
00040 class ValueStore {
00041 public:
00043         ValueStore();
00045         ValueStore(const ValueStore& other);
00047         template <class T> 
00048         ValueStore(const T& obj) 
00049                 : vptr_(detail::vtable(static_cast<const T*>(0)))
00050                 , value_(0) {
00051                 clone(&obj, &value_);
00052         }
00054         ~ValueStore();
00056         ValueStore& operator=(ValueStore other);
00058         template <class T> 
00059         ValueStore& operator=(const T& obj) {
00060                 ValueStore(obj).swap(*this);
00061                 return *this;
00062         }
00064 
00067         template <class T>
00068         ValueStore& assimilate(T* obj) {
00069                 clear();
00070                 vptr_ = detail::base_vtable(static_cast<const T*>(0));
00071                 value_= obj;
00072                 return *this;
00073         }
00075         void   swap(ValueStore& other);
00077         bool   empty()       const { return vptr_ == 0; }
00079         const  std::type_info& 
00080                      type()        const;
00082         void   clear();
00084         void   surrender();
00085 
00086         void* extract_raw() const {
00087                 return !empty() 
00088                         ? extract(const_cast<void**>(&value_))
00089                         : 0;
00090         }
00091 private:
00092         enum { call_extract = 0, vcall_clone = 1, vcall_destroy = 2, vcall_typeid = 3 };
00093         typedef detail::vptr_type vptr_type;
00094         void clone(const void* obj, void** out) const;
00095         void* extract(void** o) const;
00096         vptr_type vptr_;
00097         void*     value_;
00098 };
00099 
00100 struct bad_value_cast : std::bad_cast {
00101         const char * what() const throw() {
00102                 return "value_cast: invalid conversion on ValueStore";
00103         }
00104 };
00105 
00107 
00110 template <class T>
00111 const T& value_cast(const ValueStore& v, const T* = 0) {
00112         if (v.type() == typeid(T)) {
00113                 return *static_cast<const T*>(const_cast<const void*>(v.extract_raw()));
00114         }
00115         throw bad_value_cast();
00116 }
00118 template <class T>
00119 const T* value_cast(const ValueStore* v, const T* = 0) {
00120         if (v->type() == typeid(T)) {
00121                 return static_cast<const T*>(const_cast<const void*>(v->extract_raw()));
00122         }
00123         return 0;
00124 }
00128 template <class T>
00129 T&       value_cast(ValueStore& v, const T* p = 0) {
00130         return const_cast<T&>(value_cast(const_cast<const ValueStore&>(v), p));
00131 }
00132 template <class T>
00133 T*       value_cast(ValueStore* v, const T* p = 0) {
00134         return const_cast<T*>(value_cast(const_cast<const ValueStore*>(v), p));
00135 }
00136 
00138 template <class T>
00139 const T* unsafe_value_cast(const ValueStore* v, const T* = 0) {
00140         return static_cast<const T*>(const_cast<const void*>(v->extract_raw()));
00141 }
00145 template <class T>
00146 T*       unsafe_value_cast(ValueStore* v, const T* p = 0) {
00147         return const_cast<T*>(unsafe_value_cast(const_cast<const ValueStore*>(v), p));
00148 }
00149 
00150 #include "detail/value_store.h"
00151 
00152 }
00153 #endif


clasp
Author(s): Benjamin Kaufmann
autogenerated on Thu Aug 27 2015 12:41:40