diff options
Diffstat (limited to 'Gem/develop/include/Gem/Utils/any.h')
-rw-r--r-- | Gem/develop/include/Gem/Utils/any.h | 475 |
1 files changed, 246 insertions, 229 deletions
diff --git a/Gem/develop/include/Gem/Utils/any.h b/Gem/develop/include/Gem/Utils/any.h index 331a797..4ce48b0 100644 --- a/Gem/develop/include/Gem/Utils/any.h +++ b/Gem/develop/include/Gem/Utils/any.h @@ -30,304 +30,321 @@ namespace gem { - struct GEM_EXTERN bad_any_cast : std::bad_cast { - bad_any_cast(const std::type_info& src, const std::type_info& dest) - : result(std::string("bad cast (")+src.name() + "->" + dest.name()+")") - { } - virtual ~bad_any_cast(void) +struct GEM_EXTERN bad_any_cast : std::bad_cast { + bad_any_cast(const std::type_info& src, const std::type_info& dest) + : result(std::string("bad cast (")+src.name() + "->" + dest.name()+")") + { } + virtual ~bad_any_cast(void) #if __cplusplus <= 199711L - throw() + throw() #endif - { } - virtual const char* what(void) const + { } + virtual const char* what(void) const #if __cplusplus > 199711L - noexcept + noexcept #else - throw() + throw() #endif - { - return result.c_str(); - } - const std::string result; - }; + { + return result.c_str(); + } + const std::string result; +}; - namespace any_detail { - // function pointer table +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**); - }; +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 +// static functions for small value-types - template<bool is_small> - struct fxns +template<bool is_small> +struct fxns { + template<typename T> + struct type { + static const std::type_info& get_type(void) { - template<typename T> - struct type { - static const std::type_info& get_type(void) { - const std::type_info&res=typeid(T); - // the following is a dummy use of the type_info struct - // to make the template engine work properly on OSX/10.9 - static std::string _ = res.name(); - return res; - } - 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); - } - }; - }; + const std::type_info&res=typeid(T); + // the following is a dummy use of the type_info struct + // to make the template engine work properly on OSX/10.9 + static std::string _ = res.name(); + return res; + } + 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*) +// static functions for big value-types (bigger than a void*) - template<> - struct fxns<false> +template<> +struct fxns<false> { + template<typename T> + struct type { + static const std::type_info& get_type(void) { - template<typename T> - struct type { - static const std::type_info& get_type(void) { - const std::type_info&res=typeid(T); - return res; - } - 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 + const std::type_info&res=typeid(T); + return res; + } + static void static_delete(void** x) { - 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; - } - }; + 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*); - struct empty { + 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 }; - } // namespace any_detail + 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(); +struct GEM_EXTERN any { + // structors + + template <typename T> + any(const T& x) : table(NULL), object(NULL) + { + table = any_detail::get_table<T>::get(); #if defined(__GNUC__) && __GNUC__ >= 6 # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Wplacement-new" #endif - if (sizeof(T) <= sizeof(void*)) { - new(&object) T(x); - } - else { - object = new T(x); - } + if (sizeof(T) <= sizeof(void*)) { + new(&object) T(x); + } else { + object = new T(x); + } #if defined(__GNUC__) && __GNUC__ >= 6 # pragma GCC diagnostic pop #endif - } + } - any(void) : table(NULL), object(NULL) { - table = any_detail::get_table<any_detail::empty>::get(); - object = NULL; - } + 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); - } + 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); - } + virtual ~any(void) + { + table->static_delete(&object); + } - // assignment + // assignment - any& assign(const any& x) { - // are we copying between the same type? + any& assign(const any& x) + { + // are we copying between the same type? - if (table == x.table) { - // if so, we can avoid reallocation + 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; + 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? + 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 + 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 defined(__GNUC__) && __GNUC__ >= 6 # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Wplacement-new" #endif - 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); - } + 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; } - 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; - } #if defined(__GNUC__) && __GNUC__ >= 6 # pragma GCC diagnostic pop #endif - } - return *this; } + return *this; + } - // assignment operator - - template<typename T> - any& operator=(T const& x) { - return assign(x); - } - any& operator=(const any& x) { - return assign(x); - } + // assignment operator - // utility functions + template<typename T> + any& operator=(T const& x) + { + return assign(x); + } + any& operator=(const any& x) + { + return assign(x); + } - any& swap(any& x) { - std::swap(table, x.table); - std::swap(object, x.object); - return *this; - } + // utility functions - const std::type_info& get_type(void) const { - return table->get_type(); - } + any& swap(any& x) + { + std::swap(table, x.table); + std::swap(object, x.object); + return *this; + } - template<typename T> - const T& cast(void) const { - if (!compatible<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); - } - } + const std::type_info& get_type(void) const + { + return table->get_type(); + } - /// Returns true if the two types are the same. - bool compatible(const any& x) const { - return get_type() == x.get_type(); + template<typename T> + const T& cast(void) const + { + if (!compatible<T>()) { + throw bad_any_cast(get_type(), typeid(T)); } - /// Returns true if the two types are the same. - template<typename T> - bool compatible() const { - return (get_type() == typeid(T)); + if (sizeof(T) <= sizeof(void*)) { + return *reinterpret_cast<T const*>(&object); + } else { + return *reinterpret_cast<T const*>(object); } + } + + /// Returns true if the two types are the same. + bool compatible(const any& x) const + { + return get_type() == x.get_type(); + } + /// Returns true if the two types are the same. + template<typename T> + bool compatible() const + { + return (get_type() == typeid(T)); + } // implicit casting is disabled by default - #ifdef ANY_IMPLICIT_CASTING - // automatic casting operator +#ifdef ANY_IMPLICIT_CASTING + // automatic casting operator - template<typename T> - operator T(void) const { - return cast<T>(); - } - #endif // implicit casting + 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(); - } + 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; + void reset(void) + { + if (empty()) { + return; } + table->static_delete(&object); + table = any_detail::get_table<any_detail::empty>::get(); + object = NULL; + } - // fields + // fields - any_detail::fxn_ptr_table* table; - void* object; - }; + any_detail::fxn_ptr_table* table; + void* object; +}; - // boost::any-like casting +// 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* any_cast(any* this_) +{ + if (this_->get_type() != typeid(T)) { + throw bad_any_cast(this_->get_type(), typeid(T)); } - - template<typename T> - T const* any_cast(any const* this_) { - return any_cast<T>(const_cast<any*>(this_)); + 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_)); +} + +template<typename T> +T const& any_cast(any const& this_) +{ + return *any_cast<T>(const_cast<any*>(&this_)); +} } #ifdef _MSC_VER |