QxOrm
1.5.0
C++ Object Relational Mapping library
|
00001 /**************************************************************************** 00002 ** 00003 ** https://www.qxorm.com/ 00004 ** Copyright (C) 2013 Lionel Marty (contact@qxorm.com) 00005 ** 00006 ** This file is part of the QxOrm library 00007 ** 00008 ** This software is provided 'as-is', without any express or implied 00009 ** warranty. In no event will the authors be held liable for any 00010 ** damages arising from the use of this software 00011 ** 00012 ** Commercial Usage 00013 ** Licensees holding valid commercial QxOrm licenses may use this file in 00014 ** accordance with the commercial license agreement provided with the 00015 ** Software or, alternatively, in accordance with the terms contained in 00016 ** a written agreement between you and Lionel Marty 00017 ** 00018 ** GNU General Public License Usage 00019 ** Alternatively, this file may be used under the terms of the GNU 00020 ** General Public License version 3.0 as published by the Free Software 00021 ** Foundation and appearing in the file 'license.gpl3.txt' included in the 00022 ** packaging of this file. Please review the following information to 00023 ** ensure the GNU General Public License version 3.0 requirements will be 00024 ** met : http://www.gnu.org/copyleft/gpl.html 00025 ** 00026 ** If you are unsure which license is appropriate for your use, or 00027 ** if you have questions regarding the use of this file, please contact : 00028 ** contact@qxorm.com 00029 ** 00030 ****************************************************************************/ 00031 00032 #ifndef _QX_ANY_H_ 00033 #define _QX_ANY_H_ 00034 00035 #ifdef _MSC_VER 00036 #pragma once 00037 #endif 00038 00046 #ifndef _QX_NO_RTTI 00047 #include <typeinfo> 00048 #define QX_TYPE_ID(T) typeid(T) 00049 #else // _QX_NO_RTTI 00050 #include <QxTraits/get_class_name.h> 00051 #include <QxTraits/get_class_name_primitive.h> 00052 #define QX_TYPE_ID(T) std::string(qx::trait::get_class_name< T >::get()) 00053 #endif // _QX_NO_RTTI 00054 00055 #ifndef Q_OS_WIN 00056 #if (__GNUC__ >= 4) 00057 #define QX_ANY_FORCE_HIDDEN_VISIBILITY __attribute__ ((visibility("hidden"))) // To avoid a GCC warning : 'qx::any::holder<T>' declared with greater visibility than the type of its field 'qx::any::holder<T>::held' [-Wattributes] 00058 #endif // (__GNUC__ >= 4) 00059 #endif // Q_OS_WIN 00060 00061 #ifndef QX_ANY_FORCE_HIDDEN_VISIBILITY 00062 #define QX_ANY_FORCE_HIDDEN_VISIBILITY /* Nothing */ 00063 #endif // QX_ANY_FORCE_HIDDEN_VISIBILITY 00064 00065 namespace qx { 00066 00067 class any; 00068 template <typename ValueType> ValueType * any_cast(any *); 00069 template <typename ValueType> ValueType * unsafe_any_cast(any *); 00070 00071 class any 00072 { 00073 00074 template <typename ValueType> friend ValueType * qx::any_cast(any *); 00075 template <typename ValueType> friend ValueType * qx::unsafe_any_cast(any *); 00076 00077 public: 00078 00079 #ifndef _QX_NO_RTTI 00080 typedef const std::type_info & type_check; 00081 #else // _QX_NO_RTTI 00082 typedef std::string type_check; 00083 #endif // _QX_NO_RTTI 00084 00085 any() : content(NULL) { ; } 00086 any(const any & other) : content(other.content ? other.content->clone() : NULL) { ; } 00087 ~any() { if (content) { delete content; } } 00088 00089 template <typename ValueType> 00090 any(const ValueType & value) : content(new holder<typename std::remove_cv<typename std::decay<const ValueType>::type>::type>(value)) { ; } 00091 00092 any & swap(any & other) { std::swap(content, other.content); return (* this); } 00093 00094 template <typename ValueType> 00095 any & operator=(const ValueType & other) { any(other).swap(* this); return (* this); } 00096 00097 any & operator=(any other) { any(other).swap(* this); return (* this); } 00098 bool empty() const { return (! content); } 00099 void clear() { any().swap(* this); } 00100 type_check type() const { return (content ? content->type() : QX_TYPE_ID(void)); } 00101 00102 private: 00103 00104 struct placeholder 00105 { 00106 virtual ~placeholder() { ; } 00107 virtual type_check type() const = 0; 00108 virtual placeholder * clone() const = 0; 00109 }; 00110 00111 template <typename ValueType> 00112 struct QX_ANY_FORCE_HIDDEN_VISIBILITY holder : public placeholder 00113 { 00114 holder(const ValueType & value) : held(value) { ; } 00115 virtual type_check type() const { return QX_TYPE_ID(ValueType); } 00116 virtual placeholder * clone() const { return new holder(held); } 00117 ValueType held; 00118 00119 private: 00120 holder & operator=(const holder &); 00121 }; 00122 00123 placeholder * content; 00124 00125 }; 00126 00127 inline void swap(any & lhs, any & other) { lhs.swap(other); } 00128 00129 struct bad_any_cast : public std::exception 00130 { virtual const char * what() const throw() { return "qx::bad_any_cast : failed conversion using qx::any_cast"; } }; 00131 00132 template <typename ValueType> 00133 ValueType * any_cast(any * operand) 00134 { return ((operand && (operand->type() == QX_TYPE_ID(ValueType))) ? (& static_cast<any::holder<typename std::remove_cv<ValueType>::type> *>(operand->content)->held) : NULL); } 00135 00136 template <typename ValueType> 00137 const ValueType * any_cast(const any * operand) 00138 { return any_cast<ValueType>(const_cast<any *>(operand)); } 00139 00140 template <typename ValueType> 00141 ValueType any_cast(any & operand) 00142 { 00143 typedef typename std::remove_reference<ValueType>::type nonref; 00144 nonref * result = any_cast<nonref>(& operand); 00145 if (! result) { throw qx::bad_any_cast(); } 00146 return static_cast<ValueType>(* result); 00147 } 00148 00149 template <typename ValueType> 00150 ValueType any_cast(const any & operand) 00151 { 00152 typedef typename std::remove_reference<ValueType>::type nonref; 00153 return any_cast<const nonref &>(const_cast<any &>(operand)); 00154 } 00155 00156 template <typename ValueType> 00157 ValueType * unsafe_any_cast(any * operand) 00158 { return (& static_cast<any::holder<ValueType> *>(operand->content)->held); } 00159 00160 template <typename ValueType> 00161 const ValueType * unsafe_any_cast(const any * operand) 00162 { return unsafe_any_cast<ValueType>(const_cast<any *>(operand)); } 00163 00164 } // namespace qx 00165 00166 #endif // _QX_ANY_H_