diff options
author | Hans-Christoph Steiner <eighthave@users.sourceforge.net> | 2012-11-02 15:36:19 +0000 |
---|---|---|
committer | Hans-Christoph Steiner <eighthave@users.sourceforge.net> | 2012-11-02 15:36:19 +0000 |
commit | c823b2bf3165990a556d50990adf4da5cee95593 (patch) | |
tree | 733f3d3a6ed7a5e8f80d4b4553299902d89b58b8 /packages/noncvs/windows/extra/Gem/dev/Utils/any.h | |
parent | 2c0b722536a4ec2f723c289b695b983741c678f8 (diff) |
commit Gem 0.93.3 from http://gem.iem.at/releases/0.93.3/Gem-0.93.3-W32-i686.zip
svn path=/trunk/; revision=16521
Diffstat (limited to 'packages/noncvs/windows/extra/Gem/dev/Utils/any.h')
-rw-r--r-- | packages/noncvs/windows/extra/Gem/dev/Utils/any.h | 616 |
1 files changed, 308 insertions, 308 deletions
diff --git a/packages/noncvs/windows/extra/Gem/dev/Utils/any.h b/packages/noncvs/windows/extra/Gem/dev/Utils/any.h index 1294c8c4..597742be 100644 --- a/packages/noncvs/windows/extra/Gem/dev/Utils/any.h +++ b/packages/noncvs/windows/extra/Gem/dev/Utils/any.h @@ -1,308 +1,308 @@ -/* - * (C) Copyright Christopher Diggins 2005 - * (C) Copyright Pablo Aguilar 2005 - * (C) Copyright Kevlin Henney 2001 - * - * Copyright (C) 2010-2011 IOhannes m zmölnig. forum::für::umläute. IEM. zmoelnig@iem.at - * downloaded this code from http://www.codeproject.com/KB/cpp/dynamic_typing.aspx - * changed namespace/defines "cdiggins" to something "gem" - * - * Distributed under the Boost Software License, Version 1.0. (See - * accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - */ - -#ifndef GEM_ANY_HPP -#define GEM_ANY_HPP - -#include "Gem/ExportDef.h" - -#ifdef _MSC_VER -# pragma warning( push ) -# pragma warning( disable: 4275 ) -#endif - -#include <stdexcept> -#include <typeinfo> -#include <algorithm> - - -namespace gem -{ - struct GEM_EXTERN bad_any_cast : std::bad_cast { - bad_any_cast(const std::type_info& src, const std::type_info& dest) - : from(src.name()), to(dest.name()) - { } - virtual ~bad_any_cast(void) throw() - { } - virtual const std::string what(void) { - std::string result = std::string("bad cast("); - result+= from; - result+= std::string("->"); - result+= to; - result+= std::string(")"); - return result; - } - const std::string from; - const std::string to; - }; - - namespace any_detail { - // function pointer table - - struct fxn_ptr_table { - const std::type_info& (*get_type)(void); - void (*static_delete)(void**); - void (*clone)(void* const*, void**); - void (*move)(void* const*,void**); - }; - - // static functions for small value-types - - template<bool is_small> - struct fxns - { - template<typename T> - struct type { - static const std::type_info& get_type(void) { - return typeid(T); - } - static void static_delete(void** x) { - reinterpret_cast<T*>(x)->~T(); - } - static void clone(void* const* src, void** dest) { - new(dest) T(*reinterpret_cast<T const*>(src)); - } - static void move(void* const* src, void** dest) { - reinterpret_cast<T*>(dest)->~T(); - *reinterpret_cast<T*>(dest) = *reinterpret_cast<T const*>(src); - } - }; - }; - - // static functions for big value-types (bigger than a void*) - - template<> - struct fxns<false> - { - template<typename T> - struct type { - static const std::type_info& get_type(void) { - return typeid(T); - } - static void static_delete(void** x) { - delete(*reinterpret_cast<T**>(x)); - } - static void clone(void* const* src, void** dest) { - *dest = new T(**reinterpret_cast<T* const*>(src)); - } - static void move(void* const* src, void** dest) { - (*reinterpret_cast<T**>(dest))->~T(); - **reinterpret_cast<T**>(dest) = **reinterpret_cast<T* const*>(src); - } - }; - }; - - template<typename T> - struct get_table - { - static const bool is_small = sizeof(T) <= sizeof(void*); - - static fxn_ptr_table* get(void) - { - static fxn_ptr_table static_table = { - fxns<is_small>::template type<T>::get_type - , fxns<is_small>::template type<T>::static_delete - , fxns<is_small>::template type<T>::clone - , fxns<is_small>::template type<T>::move - }; - return &static_table; - } - }; - - struct empty { - }; - } // namespace any_detail - - - struct GEM_EXTERN any - { - // structors - - template <typename T> - any(const T& x) : table(NULL), object(NULL) { - table = any_detail::get_table<T>::get(); - if (sizeof(T) <= sizeof(void*)) { - new(&object) T(x); - } - else { - object = new T(x); - } - } - - any(void) : table(NULL), object(NULL) { - table = any_detail::get_table<any_detail::empty>::get(); - object = NULL; - } - - any(const any& x) : table(NULL), object(NULL) { - table = any_detail::get_table<any_detail::empty>::get(); - assign(x); - } - - virtual ~any(void) { - table->static_delete(&object); - } - - // assignment - - any& assign(const any& x) { - // are we copying between the same type? - - if (table == x.table) { - // if so, we can avoid reallocation - - table->move(&x.object, &object); - } - else { - reset(); - x.table->clone(&x.object, &object); - table = x.table; - } - return *this; - } - - template <typename T> - any& assign(const T& x) - { - // are we copying between the same type? - - any_detail::fxn_ptr_table* x_table = any_detail::get_table<T>::get(); - if (table == x_table) { - // if so, we can avoid deallocating and resuse memory - - if (sizeof(T) <= sizeof(void*)) { - // create copy on-top of object pointer itself - - new(&object) T(x); - } - else { - // create copy on-top of old version - - new(object) T(x); - } - } - else { - reset(); - if (sizeof(T) <= sizeof(void*)) { - // create copy on-top of object pointer itself - - new(&object) T(x); - // update table pointer - - table = x_table; - } - else { - object = new T(x); - table = x_table; - } - } - return *this; - } - - // assignment operator - - template<typename T> - any& operator=(T const& x) { - return assign(x); - } - any& operator=(const any& x) { - return assign(x); - } - - // utility functions - - any& swap(any& x) { - std::swap(table, x.table); - std::swap(object, x.object); - return *this; - } - - const std::type_info& get_type(void) const { - return table->get_type(); - } - - template<typename T> - const T& cast(void) const { - if (get_type() != typeid(T)) { - throw bad_any_cast(get_type(), typeid(T)); - } - if (sizeof(T) <= sizeof(void*)) { - return *reinterpret_cast<T const*>(&object); - } - else { - return *reinterpret_cast<T const*>(object); - } - } - - // implicit casting is disabled by default - - #ifdef ANY_IMPLICIT_CASTING - // automatic casting operator - - template<typename T> - operator T(void) const { - return cast<T>(); - } - #endif // implicit casting - - - bool empty(void) const { - return table == any_detail::get_table<any_detail::empty>::get(); - } - - void reset(void) - { - if (empty()) return; - table->static_delete(&object); - table = any_detail::get_table<any_detail::empty>::get(); - object = NULL; - } - - // fields - - any_detail::fxn_ptr_table* table; - void* object; - }; - - // boost::any-like casting - - template<typename T> - T* any_cast(any* this_) { - if (this_->get_type() != typeid(T)) { - throw bad_any_cast(this_->get_type(), typeid(T)); - } - if (sizeof(T) <= sizeof(void*)) { - return reinterpret_cast<T*>(&this_->object); - } - else { - return reinterpret_cast<T*>(this_->object); - } - } - - template<typename T> - T const* any_cast(any const* this_) { - return any_cast<T>(const_cast<any*>(this_)); - } - - template<typename T> - T const& any_cast(any const& this_){ - return *any_cast<T>(const_cast<any*>(&this_)); - } -} - -#ifdef _MSC_VER -# pragma warning( pop ) -#endif - -#endif // GEM_ANY_HPP +/*
+ * (C) Copyright Christopher Diggins 2005
+ * (C) Copyright Pablo Aguilar 2005
+ * (C) Copyright Kevlin Henney 2001
+ *
+ * Copyright (C) 2010-2011 IOhannes m zmölnig. forum::für::umläute. IEM. zmoelnig@iem.at
+ * downloaded this code from http://www.codeproject.com/KB/cpp/dynamic_typing.aspx
+ * changed namespace/defines "cdiggins" to something "gem"
+ *
+ * Distributed under the Boost Software License, Version 1.0. (See
+ * accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+#ifndef GEM_ANY_HPP
+#define GEM_ANY_HPP
+
+#include "Gem/ExportDef.h"
+
+#ifdef _MSC_VER
+# pragma warning( push )
+# pragma warning( disable: 4275 )
+#endif
+
+#include <stdexcept>
+#include <typeinfo>
+#include <algorithm>
+
+
+namespace gem
+{
+ struct GEM_EXTERN bad_any_cast : std::bad_cast {
+ bad_any_cast(const std::type_info& src, const std::type_info& dest)
+ : from(src.name()), to(dest.name())
+ { }
+ virtual ~bad_any_cast(void) throw()
+ { }
+ virtual const std::string what(void) {
+ std::string result = std::string("bad cast(");
+ result+= from;
+ result+= std::string("->");
+ result+= to;
+ result+= std::string(")");
+ return result;
+ }
+ const std::string from;
+ const std::string to;
+ };
+
+ namespace any_detail {
+ // function pointer table
+
+ struct fxn_ptr_table {
+ const std::type_info& (*get_type)(void);
+ void (*static_delete)(void**);
+ void (*clone)(void* const*, void**);
+ void (*move)(void* const*,void**);
+ };
+
+ // static functions for small value-types
+
+ template<bool is_small>
+ struct fxns
+ {
+ template<typename T>
+ struct type {
+ static const std::type_info& get_type(void) {
+ return typeid(T);
+ }
+ static void static_delete(void** x) {
+ reinterpret_cast<T*>(x)->~T();
+ }
+ static void clone(void* const* src, void** dest) {
+ new(dest) T(*reinterpret_cast<T const*>(src));
+ }
+ static void move(void* const* src, void** dest) {
+ reinterpret_cast<T*>(dest)->~T();
+ *reinterpret_cast<T*>(dest) = *reinterpret_cast<T const*>(src);
+ }
+ };
+ };
+
+ // static functions for big value-types (bigger than a void*)
+
+ template<>
+ struct fxns<false>
+ {
+ template<typename T>
+ struct type {
+ static const std::type_info& get_type(void) {
+ return typeid(T);
+ }
+ static void static_delete(void** x) {
+ delete(*reinterpret_cast<T**>(x));
+ }
+ static void clone(void* const* src, void** dest) {
+ *dest = new T(**reinterpret_cast<T* const*>(src));
+ }
+ static void move(void* const* src, void** dest) {
+ (*reinterpret_cast<T**>(dest))->~T();
+ **reinterpret_cast<T**>(dest) = **reinterpret_cast<T* const*>(src);
+ }
+ };
+ };
+
+ template<typename T>
+ struct get_table
+ {
+ static const bool is_small = sizeof(T) <= sizeof(void*);
+
+ static fxn_ptr_table* get(void)
+ {
+ static fxn_ptr_table static_table = {
+ fxns<is_small>::template type<T>::get_type
+ , fxns<is_small>::template type<T>::static_delete
+ , fxns<is_small>::template type<T>::clone
+ , fxns<is_small>::template type<T>::move
+ };
+ return &static_table;
+ }
+ };
+
+ struct empty {
+ };
+ } // namespace any_detail
+
+
+ struct GEM_EXTERN any
+ {
+ // structors
+
+ template <typename T>
+ any(const T& x) : table(NULL), object(NULL) {
+ table = any_detail::get_table<T>::get();
+ if (sizeof(T) <= sizeof(void*)) {
+ new(&object) T(x);
+ }
+ else {
+ object = new T(x);
+ }
+ }
+
+ any(void) : table(NULL), object(NULL) {
+ table = any_detail::get_table<any_detail::empty>::get();
+ object = NULL;
+ }
+
+ any(const any& x) : table(NULL), object(NULL) {
+ table = any_detail::get_table<any_detail::empty>::get();
+ assign(x);
+ }
+
+ virtual ~any(void) {
+ table->static_delete(&object);
+ }
+
+ // assignment
+
+ any& assign(const any& x) {
+ // are we copying between the same type?
+
+ if (table == x.table) {
+ // if so, we can avoid reallocation
+
+ table->move(&x.object, &object);
+ }
+ else {
+ reset();
+ x.table->clone(&x.object, &object);
+ table = x.table;
+ }
+ return *this;
+ }
+
+ template <typename T>
+ any& assign(const T& x)
+ {
+ // are we copying between the same type?
+
+ any_detail::fxn_ptr_table* x_table = any_detail::get_table<T>::get();
+ if (table == x_table) {
+ // if so, we can avoid deallocating and resuse memory
+
+ if (sizeof(T) <= sizeof(void*)) {
+ // create copy on-top of object pointer itself
+
+ new(&object) T(x);
+ }
+ else {
+ // create copy on-top of old version
+
+ new(object) T(x);
+ }
+ }
+ else {
+ reset();
+ if (sizeof(T) <= sizeof(void*)) {
+ // create copy on-top of object pointer itself
+
+ new(&object) T(x);
+ // update table pointer
+
+ table = x_table;
+ }
+ else {
+ object = new T(x);
+ table = x_table;
+ }
+ }
+ return *this;
+ }
+
+ // assignment operator
+
+ template<typename T>
+ any& operator=(T const& x) {
+ return assign(x);
+ }
+ any& operator=(const any& x) {
+ return assign(x);
+ }
+
+ // utility functions
+
+ any& swap(any& x) {
+ std::swap(table, x.table);
+ std::swap(object, x.object);
+ return *this;
+ }
+
+ const std::type_info& get_type(void) const {
+ return table->get_type();
+ }
+
+ template<typename T>
+ const T& cast(void) const {
+ if (get_type() != typeid(T)) {
+ throw bad_any_cast(get_type(), typeid(T));
+ }
+ if (sizeof(T) <= sizeof(void*)) {
+ return *reinterpret_cast<T const*>(&object);
+ }
+ else {
+ return *reinterpret_cast<T const*>(object);
+ }
+ }
+
+ // implicit casting is disabled by default
+
+ #ifdef ANY_IMPLICIT_CASTING
+ // automatic casting operator
+
+ template<typename T>
+ operator T(void) const {
+ return cast<T>();
+ }
+ #endif // implicit casting
+
+
+ bool empty(void) const {
+ return table == any_detail::get_table<any_detail::empty>::get();
+ }
+
+ void reset(void)
+ {
+ if (empty()) return;
+ table->static_delete(&object);
+ table = any_detail::get_table<any_detail::empty>::get();
+ object = NULL;
+ }
+
+ // fields
+
+ any_detail::fxn_ptr_table* table;
+ void* object;
+ };
+
+ // boost::any-like casting
+
+ template<typename T>
+ T* any_cast(any* this_) {
+ if (this_->get_type() != typeid(T)) {
+ throw bad_any_cast(this_->get_type(), typeid(T));
+ }
+ if (sizeof(T) <= sizeof(void*)) {
+ return reinterpret_cast<T*>(&this_->object);
+ }
+ else {
+ return reinterpret_cast<T*>(this_->object);
+ }
+ }
+
+ template<typename T>
+ T const* any_cast(any const* this_) {
+ return any_cast<T>(const_cast<any*>(this_));
+ }
+
+ template<typename T>
+ T const& any_cast(any const& this_){
+ return *any_cast<T>(const_cast<any*>(&this_));
+ }
+}
+
+#ifdef _MSC_VER
+# pragma warning( pop )
+#endif
+
+#endif // GEM_ANY_HPP
|