![]() |
QxOrm
1.4.1
C++ Object Relational Mapping library
|
00001 /**************************************************************************** 00002 ** 00003 ** http://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_CONVERT_IMPL_H_ 00033 #define _QX_CONVERT_IMPL_H_ 00034 00035 #ifdef _MSC_VER 00036 #pragma once 00037 #endif 00038 00039 #include <boost/mpl/if.hpp> 00040 #include <boost/mpl/logical.hpp> 00041 #include <boost/type_traits/is_pointer.hpp> 00042 #include <boost/type_traits/is_enum.hpp> 00043 #include <boost/static_assert.hpp> 00044 00045 #include <QxConvert/QxConvert.h> 00046 #include <QxCommon/QxBool.h> 00047 00048 #include <QxDao/QxDateNeutral.h> 00049 #include <QxDao/QxTimeNeutral.h> 00050 #include <QxDao/QxDateTimeNeutral.h> 00051 #include <QxDao/QxSqlQuery.h> 00052 00053 #include <QxCollection/QxCollection.h> 00054 00055 #include <QxRegister/QxClass.h> 00056 00057 #include <QxSerialize/QxArchive.h> 00058 #include <QxSerialize/QxSerializeQDataStream.h> 00059 #include <QxSerialize/QDataStream/QxSerializeQDataStream_all_include.h> 00060 00061 #include <QxValidator/QxInvalidValue.h> 00062 #include <QxValidator/QxInvalidValueX.h> 00063 00064 #include <QxTraits/is_smart_ptr.h> 00065 #include <QxTraits/is_container.h> 00066 #include <QxTraits/is_qx_registered.h> 00067 #include <QxTraits/is_qt_variant_compatible.h> 00068 #include <QxTraits/get_class_name_primitive.h> 00069 #include <QxTraits/construct_ptr.h> 00070 #include <QxTraits/generic_container.h> 00071 00072 #define QX_STR_CVT_QDATE_FORMAT "yyyyMMdd" 00073 #define QX_STR_CVT_QTIME_FORMAT "hhmmsszzz" 00074 #define QX_STR_CVT_QDATETIME_FORMAT "yyyyMMddhhmmsszzz" 00075 00076 #ifdef _QX_ENABLE_BOOST_SERIALIZATION 00077 #if _QX_SERIALIZE_POLYMORPHIC 00078 #define QX_CVT_DEFAULT_ARCHIVE qx::serialization::polymorphic_xml 00079 #elif _QX_SERIALIZE_XML 00080 #define QX_CVT_DEFAULT_ARCHIVE qx::serialization::xml 00081 #elif _QX_SERIALIZE_TEXT 00082 #define QX_CVT_DEFAULT_ARCHIVE qx::serialization::text 00083 #elif _QX_SERIALIZE_BINARY 00084 #define QX_CVT_DEFAULT_ARCHIVE qx::serialization::binary 00085 #endif // _QX_SERIALIZE_XML 00086 #else // _QX_ENABLE_BOOST_SERIALIZATION 00087 #define QX_CVT_DEFAULT_ARCHIVE qx::serialization::qt 00088 #endif // _QX_ENABLE_BOOST_SERIALIZATION 00089 00090 #define QX_CVT_USING_ARCHIVE_IMPL(className) \ 00091 namespace qx { namespace cvt { namespace detail { \ 00092 template <> struct QxConvert_ToString< className > { \ 00093 static inline QString toString(const className & t, const QString & format, int index) \ 00094 { Q_UNUSED(format); Q_UNUSED(index); return QX_CVT_DEFAULT_ARCHIVE::to_string(t); } }; \ 00095 template <> struct QxConvert_FromString< className > { \ 00096 static inline qx_bool fromString(const QString & s, className & t, const QString & format, int index) \ 00097 { Q_UNUSED(format); Q_UNUSED(index); return QX_CVT_DEFAULT_ARCHIVE::from_string(t, s); } }; \ 00098 template <> struct QxConvert_ToVariant< className > { \ 00099 static inline QVariant toVariant(const className & t, const QString & format, int index) \ 00100 { Q_UNUSED(format); Q_UNUSED(index); return QX_CVT_DEFAULT_ARCHIVE::to_string(t); } }; \ 00101 template <> struct QxConvert_FromVariant< className > { \ 00102 static inline qx_bool fromVariant(const QVariant & v, className & t, const QString & format, int index) \ 00103 { Q_UNUSED(format); Q_UNUSED(index); QString s = v.toString(); return QX_CVT_DEFAULT_ARCHIVE::from_string(t, s); } }; \ 00104 } } } // namespace qx::cvt::detail 00105 00106 namespace qx { 00107 namespace cvt { 00108 namespace detail { 00109 namespace helper { 00110 00111 struct QxConvertHelper_Generic { }; 00112 struct QxConvertHelper_Ptr { }; 00113 struct QxConvertHelper_Registered { }; 00114 struct QxConvertHelper_Container { }; 00115 struct QxConvertHelper_Enum { }; 00116 00117 struct QxConvertFormat { static inline bool isValid(const QString & format) { return ((! format.isEmpty()) && (format != QX_FORMAT_FROM_SERIALIZE_REGISTERED)); } }; 00118 00119 } // namespace helper 00120 00121 template <typename T, typename H> 00122 struct QxConvertHelper_ToString 00123 { 00124 static inline QString toString(const T & t, const QString & format, int index) 00125 { qAssertMsg(false, "qx::cvt::detail::QxConvertHelper_ToString", "template must be specialized"); Q_UNUSED(t); Q_UNUSED(format); Q_UNUSED(index); return QString(); } 00126 }; 00127 00128 template <typename T, typename H> 00129 struct QxConvertHelper_FromString 00130 { 00131 static inline qx_bool fromString(const QString & s, T & t, const QString & format, int index) 00132 { qAssertMsg(false, "qx::cvt::detail::QxConvertHelper_FromString", "template must be specialized"); Q_UNUSED(s); Q_UNUSED(t); Q_UNUSED(format); Q_UNUSED(index); return qx_bool(); } 00133 }; 00134 00135 template <typename T, typename H> 00136 struct QxConvertHelper_ToVariant 00137 { 00138 static inline QVariant toVariant(const T & t, const QString & format, int index) 00139 { qAssertMsg(false, "qx::cvt::detail::QxConvertHelper_ToVariant", "template must be specialized"); Q_UNUSED(t); Q_UNUSED(format); Q_UNUSED(index); return QVariant(); } 00140 }; 00141 00142 template <typename T, typename H> 00143 struct QxConvertHelper_FromVariant 00144 { 00145 static inline qx_bool fromVariant(const QVariant & v, T & t, const QString & format, int index) 00146 { qAssertMsg(false, "qx::cvt::detail::QxConvertHelper_FromVariant", "template must be specialized"); Q_UNUSED(v); Q_UNUSED(t); Q_UNUSED(format); Q_UNUSED(index); return qx_bool(); } 00147 }; 00148 00149 template <typename T> 00150 struct QxConvertHelper_ToString<T, qx::cvt::detail::helper::QxConvertHelper_Generic> 00151 { 00152 00153 enum { qx_need_to_specialize_template_convert_to_string_from_string = 0 }; 00154 00155 static inline QString toString(const T & t, const QString & format, int index) 00156 { 00157 Q_UNUSED(t); Q_UNUSED(format); Q_UNUSED(index); 00158 BOOST_STATIC_ASSERT(qx_need_to_specialize_template_convert_to_string_from_string); // If a compilation error occurred here : you have to specialize template 'qx::cvt::detail::QxConvert_ToString< MyType >' 00159 return QString(); 00160 00161 /* 00162 std::string s; 00163 try { s = boost::lexical_cast<std::string>(t); } 00164 catch (...) { qDebug("[QxOrm] %s", "'QxConvertHelper_ToString::toString()' unknown error calling 'boost::lexical_cast<std::string>()'"); s = ""; } 00165 #ifndef QT_NO_STL 00166 return QString::fromStdString(s); 00167 #else // QT_NO_STL 00168 return QString::fromLatin1(s.data(), int(s.size())); 00169 #endif // QT_NO_STL 00170 */ 00171 } 00172 00173 }; 00174 00175 template <typename T> 00176 struct QxConvertHelper_FromString<T, qx::cvt::detail::helper::QxConvertHelper_Generic> 00177 { 00178 00179 enum { qx_need_to_specialize_template_convert_to_string_from_string = 0 }; 00180 00181 static inline qx_bool fromString(const QString & s, T & t, const QString & format, int index) 00182 { 00183 Q_UNUSED(s); Q_UNUSED(t); Q_UNUSED(format); Q_UNUSED(index); 00184 BOOST_STATIC_ASSERT(qx_need_to_specialize_template_convert_to_string_from_string); // If a compilation error occurred here : you have to specialize template 'qx::cvt::detail::QxConvert_FromString< MyType >' 00185 return qx_bool(true); 00186 00187 /* 00188 #ifndef QT_NO_STL 00189 try { t = boost::lexical_cast<T>(s.toStdString()); } 00190 #else // QT_NO_STL 00191 try { std::string tmp(s.toLatin1().constData()); t = boost::lexical_cast<T>(tmp); } 00192 #endif // QT_NO_STL 00193 catch (...) { qDebug("[QxOrm] %s", "'QxConvertHelper_FromString::fromString()' unknown error calling 'boost::lexical_cast<T>()'"); return qx_bool(false); } 00194 return qx_bool(true); 00195 */ 00196 } 00197 00198 }; 00199 00200 template <typename T> 00201 struct QxConvertHelper_ToVariant<T, qx::cvt::detail::helper::QxConvertHelper_Generic> 00202 { 00203 00204 static inline QVariant toVariant(const T & t, const QString & format, int index) 00205 { return cvtQVariant<qx::trait::is_qt_variant_compatible<T>::value, 0>::toVariant(t, format, index); } 00206 00207 private: 00208 00209 template <bool isQVariantCompatible /* = false */, int dummy> 00210 struct cvtQVariant 00211 { static inline QVariant toVariant(const T & t, const QString & format, int index) { return qx::cvt::to_string(t, format, index); }; }; 00212 00213 template <int dummy> 00214 struct cvtQVariant<true, dummy> 00215 { static inline QVariant toVariant(const T & t, const QString & format, int index) { Q_UNUSED(format); Q_UNUSED(index); return QVariant(t); }; }; 00216 00217 }; 00218 00219 template <typename T> 00220 struct QxConvertHelper_FromVariant<T, qx::cvt::detail::helper::QxConvertHelper_Generic> 00221 { 00222 00223 static inline qx_bool fromVariant(const QVariant & v, T & t, const QString & format, int index) 00224 { return cvtQVariant<qx::trait::is_qt_variant_compatible<T>::value, 0>::fromVariant(v, t, format, index); } 00225 00226 private: 00227 00228 template <bool isQVariantCompatible /* = false */, int dummy> 00229 struct cvtQVariant 00230 { static inline qx_bool fromVariant(const QVariant & v, T & t, const QString & format, int index) { return qx::cvt::from_string(v.toString(), t, format, index); }; }; 00231 00232 template <int dummy> 00233 struct cvtQVariant<true, dummy> 00234 { static inline qx_bool fromVariant(const QVariant & v, T & t, const QString & format, int index) { Q_UNUSED(format); Q_UNUSED(index); t = v.value<T>(); return qx_bool(true); }; }; 00235 00236 }; 00237 00238 template <typename T> 00239 struct QxConvertHelper_ToString<T, qx::cvt::detail::helper::QxConvertHelper_Ptr> 00240 { 00241 static inline QString toString(const T & t, const QString & format, int index) 00242 { return (t ? qx::cvt::to_string((* t), format, index) : ""); } 00243 }; 00244 00245 template <typename T> 00246 struct QxConvertHelper_FromString<T, qx::cvt::detail::helper::QxConvertHelper_Ptr> 00247 { 00248 static inline qx_bool fromString(const QString & s, T & t, const QString & format, int index) 00249 { if (! t) { qx::trait::construct_ptr<T>::get(t); }; return (t ? qx::cvt::from_string(s, (* t), format, index) : qx_bool(false)); } 00250 }; 00251 00252 template <typename T> 00253 struct QxConvertHelper_ToVariant<T, qx::cvt::detail::helper::QxConvertHelper_Ptr> 00254 { 00255 static inline QVariant toVariant(const T & t, const QString & format, int index) 00256 { return (t ? qx::cvt::to_variant((* t), format, index) : QVariant()); } 00257 }; 00258 00259 template <typename T> 00260 struct QxConvertHelper_FromVariant<T, qx::cvt::detail::helper::QxConvertHelper_Ptr> 00261 { 00262 static inline qx_bool fromVariant(const QVariant & v, T & t, const QString & format, int index) 00263 { if (! t && ! v.isNull()) { qx::trait::construct_ptr<T>::get(t); }; return (t ? qx::cvt::from_variant(v, (* t), format, index) : qx_bool(false)); } 00264 }; 00265 00266 template <typename T> 00267 struct QxConvertHelper_ToString<T, qx::cvt::detail::helper::QxConvertHelper_Registered> 00268 { 00269 static inline QString toString(const T & t, const QString & format, int index) 00270 { 00271 if (format.isEmpty() || (format != QX_FORMAT_FROM_SERIALIZE_REGISTERED)) 00272 { qx::IxDataMember * pId = qx::QxClass<T>::getSingleton()->getDataMemberX()->getId_WithDaoStrategy(); return (pId ? pId->toVariant((& t), format, index).toString() : QString()); } 00273 return qx::serialization::qt::to_string<T>(t); 00274 } 00275 }; 00276 00277 template <typename T> 00278 struct QxConvertHelper_FromString<T, qx::cvt::detail::helper::QxConvertHelper_Registered> 00279 { 00280 static inline qx_bool fromString(const QString & s, T & t, const QString & format, int index) 00281 { 00282 if (format.isEmpty() || (format != QX_FORMAT_FROM_SERIALIZE_REGISTERED)) 00283 { qx::IxDataMember * pId = qx::QxClass<T>::getSingleton()->getDataMemberX()->getId_WithDaoStrategy(); QVariant tmp(s); return (pId ? pId->fromVariant((& t), tmp, format, index) : qx_bool(false)); } 00284 return qx::serialization::qt::from_string<T>(t, s); 00285 } 00286 }; 00287 00288 template <typename T> 00289 struct QxConvertHelper_ToVariant<T, qx::cvt::detail::helper::QxConvertHelper_Registered> 00290 { 00291 static inline QVariant toVariant(const T & t, const QString & format, int index) 00292 { 00293 if (format.isEmpty() || (format != QX_FORMAT_FROM_SERIALIZE_REGISTERED)) 00294 { qx::IxDataMember * pId = qx::QxClass<T>::getSingleton()->getDataMemberX()->getId_WithDaoStrategy(); return (pId ? pId->toVariant((& t), format, index) : QVariant()); } 00295 return qx::serialization::qt::to_byte_array<T>(t); 00296 } 00297 }; 00298 00299 template <typename T> 00300 struct QxConvertHelper_FromVariant<T, qx::cvt::detail::helper::QxConvertHelper_Registered> 00301 { 00302 static inline qx_bool fromVariant(const QVariant & v, T & t, const QString & format, int index) 00303 { 00304 if (format.isEmpty() || (format != QX_FORMAT_FROM_SERIALIZE_REGISTERED)) 00305 { qx::IxDataMember * pId = qx::QxClass<T>::getSingleton()->getDataMemberX()->getId_WithDaoStrategy(); return (pId ? pId->fromVariant((& t), v, format, index) : qx_bool(false)); } 00306 return qx::serialization::qt::from_byte_array<T>(t, v.toByteArray()); 00307 } 00308 }; 00309 00310 template <typename T> 00311 struct QxConvertHelper_ToString<T, qx::cvt::detail::helper::QxConvertHelper_Container> 00312 { 00313 static inline QString toString(const T & t, const QString & format, int index) 00314 { Q_UNUSED(format); Q_UNUSED(index); return QX_CVT_DEFAULT_ARCHIVE::to_string(t); } 00315 }; 00316 00317 template <typename T> 00318 struct QxConvertHelper_FromString<T, qx::cvt::detail::helper::QxConvertHelper_Container> 00319 { 00320 static inline qx_bool fromString(const QString & s, T & t, const QString & format, int index) 00321 { Q_UNUSED(format); Q_UNUSED(index); return QX_CVT_DEFAULT_ARCHIVE::from_string(t, s); } 00322 }; 00323 00324 template <typename T> 00325 struct QxConvertHelper_ToVariant<T, qx::cvt::detail::helper::QxConvertHelper_Container> 00326 { 00327 static inline QVariant toVariant(const T & t, const QString & format, int index) 00328 { Q_UNUSED(format); Q_UNUSED(index); return QX_CVT_DEFAULT_ARCHIVE::to_string(t); } 00329 }; 00330 00331 template <typename T> 00332 struct QxConvertHelper_FromVariant<T, qx::cvt::detail::helper::QxConvertHelper_Container> 00333 { 00334 static inline qx_bool fromVariant(const QVariant & v, T & t, const QString & format, int index) 00335 { Q_UNUSED(format); Q_UNUSED(index); return QX_CVT_DEFAULT_ARCHIVE::from_string(t, v.toString()); } 00336 }; 00337 00338 template <typename T> 00339 struct QxConvertHelper_ToString<T, qx::cvt::detail::helper::QxConvertHelper_Enum> 00340 { 00341 static inline QString toString(const T & t, const QString & format, int index) 00342 { Q_UNUSED(format); Q_UNUSED(index); return QString::number(static_cast<long>(t)); } 00343 }; 00344 00345 template <typename T> 00346 struct QxConvertHelper_FromString<T, qx::cvt::detail::helper::QxConvertHelper_Enum> 00347 { 00348 static inline qx_bool fromString(const QString & s, T & t, const QString & format, int index) 00349 { Q_UNUSED(format); Q_UNUSED(index); bool bOk = false; t = static_cast<T>(static_cast<long>(s.toLongLong(& bOk))); return bOk; } 00350 }; 00351 00352 template <typename T> 00353 struct QxConvertHelper_ToVariant<T, qx::cvt::detail::helper::QxConvertHelper_Enum> 00354 { 00355 static inline QVariant toVariant(const T & t, const QString & format, int index) 00356 { Q_UNUSED(format); Q_UNUSED(index); return QVariant(static_cast<qlonglong>(t)); } 00357 }; 00358 00359 template <typename T> 00360 struct QxConvertHelper_FromVariant<T, qx::cvt::detail::helper::QxConvertHelper_Enum> 00361 { 00362 static inline qx_bool fromVariant(const QVariant & v, T & t, const QString & format, int index) 00363 { Q_UNUSED(format); Q_UNUSED(index); bool bOk = false; t = static_cast<T>(static_cast<long>(v.toLongLong(& bOk))); return bOk; } 00364 }; 00365 00366 template <typename T> 00367 struct QxConvertHelper 00368 { 00369 00370 private: 00371 00372 typedef typename boost::mpl::if_c< boost::is_pointer<T>::value, qx::cvt::detail::helper::QxConvertHelper_Ptr, qx::cvt::detail::helper::QxConvertHelper_Generic >::type type_str_cvt_helper_1; 00373 typedef typename boost::mpl::if_c< qx::trait::is_smart_ptr<T>::value, qx::cvt::detail::helper::QxConvertHelper_Ptr, type_str_cvt_helper_1 >::type type_str_cvt_helper_2; 00374 typedef typename boost::mpl::if_c< qx::trait::is_container<T>::value, qx::cvt::detail::helper::QxConvertHelper_Container, type_str_cvt_helper_2 >::type type_str_cvt_helper_3; 00375 typedef typename boost::mpl::if_c< qx::trait::is_qx_registered<T>::value, qx::cvt::detail::helper::QxConvertHelper_Registered, type_str_cvt_helper_3 >::type type_str_cvt_helper_4; 00376 typedef typename boost::mpl::if_c< boost::is_enum<T>::value, qx::cvt::detail::helper::QxConvertHelper_Enum, type_str_cvt_helper_4 >::type type_str_cvt_helper_5; 00377 00378 public: 00379 00380 typedef typename QxConvertHelper<T>::type_str_cvt_helper_5 type; 00381 00382 }; 00383 00384 template <typename T> 00385 struct QxConvert_ToString 00386 { 00387 static inline QString toString(const T & t, const QString & format, int index) 00388 { return qx::cvt::detail::QxConvertHelper_ToString<T, typename qx::cvt::detail::QxConvertHelper<T>::type>::toString(t, format, index); } 00389 }; 00390 00391 template <typename T> 00392 struct QxConvert_FromString 00393 { 00394 static inline qx_bool fromString(const QString & s, T & t, const QString & format, int index) 00395 { return qx::cvt::detail::QxConvertHelper_FromString<T, typename qx::cvt::detail::QxConvertHelper<T>::type>::fromString(s, t, format, index); } 00396 }; 00397 00398 template <typename T> 00399 struct QxConvert_ToVariant 00400 { 00401 static inline QVariant toVariant(const T & t, const QString & format, int index) 00402 { return qx::cvt::detail::QxConvertHelper_ToVariant<T, typename qx::cvt::detail::QxConvertHelper<T>::type>::toVariant(t, format, index); } 00403 }; 00404 00405 template <typename T> 00406 struct QxConvert_FromVariant 00407 { 00408 static inline qx_bool fromVariant(const QVariant & v, T & t, const QString & format, int index) 00409 { return qx::cvt::detail::QxConvertHelper_FromVariant<T, typename qx::cvt::detail::QxConvertHelper<T>::type>::fromVariant(v, t, format, index); } 00410 }; 00411 00412 } // namespace detail 00413 } // namespace cvt 00414 } // namespace qx 00415 00416 #include "../../inl/QxConvert/QxConvert_WithIndex.inl" 00417 #include "../../inl/QxConvert/QxConvert_ToString.inl" 00418 #include "../../inl/QxConvert/QxConvert_FromString.inl" 00419 #include "../../inl/QxConvert/QxConvert_ToVariant.inl" 00420 #include "../../inl/QxConvert/QxConvert_FromVariant.inl" 00421 #include "../../inl/QxConvert/QxConvert_Qt.inl" 00422 00423 #endif // _QX_CONVERT_IMPL_H_