diff --git a/.gitignore b/.gitignore index ce734c4..9a073a8 100644 --- a/.gitignore +++ b/.gitignore @@ -28,6 +28,7 @@ qtc-gdbmacros/ *.o *.a moc_* +build/ *.cmake CMakeFiles/ diff --git a/include/camp/qt/qtfunction.hpp b/include/camp/qt/qtfunction.hpp index 96484ab..912383b 100644 --- a/include/camp/qt/qtfunction.hpp +++ b/include/camp/qt/qtfunction.hpp @@ -15,10 +15,10 @@ ** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell ** copies of the Software, and to permit persons to whom the Software is ** furnished to do so, subject to the following conditions: -** +** ** The above copyright notice and this permission notice shall be included in ** all copies or substantial portions of the Software. -** +** ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -86,7 +86,7 @@ class QtFunction : public camp::Function case 1: { - QVariant arg1 = QtHelper::valueToVariant(args[0]); + const auto arg1 = QtHelper::argumentToVariant(args[0], m_metaMethod.parameterType(0)); m_metaMethod.invoke(object.get(), Qt::DirectConnection, ret , QGenericArgument(arg1.typeName(), arg1.data())); break; @@ -94,8 +94,8 @@ class QtFunction : public camp::Function case 2: { - QVariant arg1 = QtHelper::valueToVariant(args[0]); - QVariant arg2 = QtHelper::valueToVariant(args[1]); + const auto arg1 = QtHelper::argumentToVariant(args[0], m_metaMethod.parameterType(0)); + const auto arg2 = QtHelper::argumentToVariant(args[1], m_metaMethod.parameterType(1)); m_metaMethod.invoke(object.get(), Qt::DirectConnection, ret , QGenericArgument(arg1.typeName(), arg1.data()) , QGenericArgument(arg2.typeName(), arg2.data())); @@ -104,9 +104,9 @@ class QtFunction : public camp::Function case 3: { - QVariant arg1 = QtHelper::valueToVariant(args[0]); - QVariant arg2 = QtHelper::valueToVariant(args[1]); - QVariant arg3 = QtHelper::valueToVariant(args[2]); + const auto arg1 = QtHelper::argumentToVariant(args[0], m_metaMethod.parameterType(0)); + const auto arg2 = QtHelper::argumentToVariant(args[1], m_metaMethod.parameterType(1)); + const auto arg3 = QtHelper::argumentToVariant(args[2], m_metaMethod.parameterType(2)); m_metaMethod.invoke(object.get(), Qt::DirectConnection, ret , QGenericArgument(arg1.typeName(), arg1.data()) , QGenericArgument(arg2.typeName(), arg2.data()) @@ -116,10 +116,10 @@ class QtFunction : public camp::Function case 4: { - QVariant arg1 = QtHelper::valueToVariant(args[0]); - QVariant arg2 = QtHelper::valueToVariant(args[1]); - QVariant arg3 = QtHelper::valueToVariant(args[2]); - QVariant arg4 = QtHelper::valueToVariant(args[3]); + const auto arg1 = QtHelper::argumentToVariant(args[0], m_metaMethod.parameterType(0)); + const auto arg2 = QtHelper::argumentToVariant(args[1], m_metaMethod.parameterType(1)); + const auto arg3 = QtHelper::argumentToVariant(args[2], m_metaMethod.parameterType(2)); + const auto arg4 = QtHelper::argumentToVariant(args[3], m_metaMethod.parameterType(3)); m_metaMethod.invoke(object.get(), Qt::DirectConnection, ret , QGenericArgument(arg1.typeName(), arg1.data()) , QGenericArgument(arg2.typeName(), arg2.data()) @@ -130,11 +130,11 @@ class QtFunction : public camp::Function case 5: { - QVariant arg1 = QtHelper::valueToVariant(args[0]); - QVariant arg2 = QtHelper::valueToVariant(args[1]); - QVariant arg3 = QtHelper::valueToVariant(args[2]); - QVariant arg4 = QtHelper::valueToVariant(args[3]); - QVariant arg5 = QtHelper::valueToVariant(args[4]); + const auto arg1 = QtHelper::argumentToVariant(args[0], m_metaMethod.parameterType(0)); + const auto arg2 = QtHelper::argumentToVariant(args[1], m_metaMethod.parameterType(1)); + const auto arg3 = QtHelper::argumentToVariant(args[2], m_metaMethod.parameterType(2)); + const auto arg4 = QtHelper::argumentToVariant(args[3], m_metaMethod.parameterType(3)); + const auto arg5 = QtHelper::argumentToVariant(args[4], m_metaMethod.parameterType(4)); m_metaMethod.invoke(object.get(), Qt::DirectConnection, ret , QGenericArgument(arg1.typeName(), arg1.data()) , QGenericArgument(arg2.typeName(), arg2.data()) diff --git a/include/camp/qt/qthelper.hpp b/include/camp/qt/qthelper.hpp index 154b24c..0050718 100644 --- a/include/camp/qt/qthelper.hpp +++ b/include/camp/qt/qthelper.hpp @@ -15,10 +15,10 @@ ** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell ** copies of the Software, and to permit persons to whom the Software is ** furnished to do so, subject to the following conditions: -** +** ** The above copyright notice and this permission notice shall be included in ** all copies or substantial portions of the Software. -** +** ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -105,11 +105,11 @@ class QtHelper case QMetaType::QString: return QVariant::String; case QMetaType::QByteArray: return QVariant::ByteArray; case QMetaType::VoidStar: return QVariant::Invalid; - case QMetaType::Long: return QVariant::Int; + case QMetaType::Long: return (sizeof(int) == sizeof(long)) ? QVariant::Int : QVariant::LongLong; case QMetaType::LongLong: return QVariant::LongLong; case QMetaType::Short: return QVariant::Int; case QMetaType::Char: return QVariant::Char; - case QMetaType::ULong: return QVariant::UInt; + case QMetaType::ULong: return (sizeof(int) == sizeof(long)) ? QVariant::UInt : QVariant::ULongLong; case QMetaType::ULongLong: return QVariant::ULongLong; case QMetaType::UShort: return QVariant::UInt; case QMetaType::UChar: return QVariant::Char; @@ -166,12 +166,18 @@ class QtHelper */ static QVariant valueToVariant(const camp::Value& value) { + auto toInt = [](const camp::Value& value) + { + return value.to() > static_cast(std::numeric_limits::max()) + ? QVariant(value.to()) + : QVariant(value.to()); + }; switch (value.type()) { default: case camp::noType: return QVariant(); case camp::boolType: return QVariant(value.to()); - case camp::intType: return QVariant(value.to()); + case camp::intType: return toInt(value); case camp::realType: return QVariant(value.to()); case camp::stringType: return QVariant(value.to()); case camp::enumType: return QVariant(value.to()); @@ -179,6 +185,38 @@ class QtHelper } } + /** + * \brief Convert a CAMP value to a QGenericArgument + * + * \param value Source camp::Value to convert + * + * \return \a value converted to a QGenericArgument + */ + static QVariant argumentToVariant(const camp::Value& value, int metaType) + { + switch (metaType) + { + default: + case QMetaType::Void: return QVariant(); + case QMetaType::Bool: return value.to(); + case QMetaType::Int: return value.to(); + case QMetaType::UInt: return value.to(); + case QMetaType::Double: return value.to(); + case QMetaType::QChar: return value.to(); + case QMetaType::QString: return value.to(); + case QMetaType::Long: return sizeof(int) == sizeof(long) ? value.to(): value.to(); + case QMetaType::LongLong: return value.to(); + case QMetaType::Short: return value.to(); + case QMetaType::Char: return value.to(); + case QMetaType::ULong: return sizeof(int) == sizeof(long) ? value.to(): value.to(); + case QMetaType::ULongLong: return value.to();; + case QMetaType::UShort: return value.to();; + case QMetaType::UChar: return value.to();; + case QMetaType::Float: return value.to(); + } + } + + /** * \brief Convert a QVariant to a CAMP value * diff --git a/include/camp/valuemapper.hpp b/include/camp/valuemapper.hpp index d02e432..96f277b 100644 --- a/include/camp/valuemapper.hpp +++ b/include/camp/valuemapper.hpp @@ -15,10 +15,10 @@ ** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell ** copies of the Software, and to permit persons to whom the Software is ** furnished to do so, subject to the following conditions: -** +** ** The above copyright notice and this permission notice shall be included in ** all copies or substantial portions of the Software. -** +** ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -40,8 +40,8 @@ #include #include #include -#include -#include + +#include namespace camp_ext @@ -94,13 +94,13 @@ namespace camp_ext * { * // The corresponding CAMP type is "string" * static const int type = camp::string; - * + * * // Convert from MyStringClass to std::string * static std::string to(const MyStringClass& source) * { * return source.to_std_string(); * } - * + * * // Convert from any type to MyStringClass * // Be smart, juste reuse ValueMapper :) * template @@ -124,7 +124,9 @@ struct ValueMapper static camp::UserObject to(const T& source) {return camp::UserObject(source);} static T from(bool) {CAMP_ERROR(camp::BadType(camp::boolType, camp::mapType()));} + static T from(int) {CAMP_ERROR(camp::BadType(camp::intType, camp::mapType()));} static T from(long) {CAMP_ERROR(camp::BadType(camp::intType, camp::mapType()));} + static T from(long long) {CAMP_ERROR(camp::BadType(camp::intType, camp::mapType()));} static T from(double) {CAMP_ERROR(camp::BadType(camp::realType, camp::mapType()));} static T from(const std::string&) {CAMP_ERROR(camp::BadType(camp::stringType, camp::mapType()));} static T from(const camp::EnumObject&) {CAMP_ERROR(camp::BadType(camp::enumType, camp::mapType()));} @@ -135,7 +137,7 @@ struct ValueMapper * Specialization of ValueMapper for abstract types */ template -struct ValueMapper >::type> +struct ValueMapper::value >::type> { static const int type = camp::userType; static camp::UserObject to(const T& source) {return camp::UserObject(source);} @@ -152,8 +154,9 @@ struct ValueMapper static bool from(bool source) {return source;} static bool from(long source) {return source != 0;} + static bool from(long long source) {return source != 0;} static bool from(double source) {return source != 0.;} - static bool from(const std::string& source) + static bool from(const std::string& source) { bool result; if(source.compare("true") == 0) @@ -178,16 +181,18 @@ struct ValueMapper * Specialization of ValueMapper for integers */ template -struct ValueMapper::value - && !boost::is_const::value // to avoid conflict with ValueMapper - && !boost::is_reference::value // to avoid conflict with ValueMapper - >::type> +struct ValueMapper::value + && !std::is_const::value // to avoid conflict with ValueMapper + && !std::is_reference::value // to avoid conflict with ValueMapper + >::type> { static const int type = camp::intType; static long to(T source) {return static_cast(source);} static T from(bool source) {return static_cast(source);} + static T from(int source) {return static_cast(source);} static T from(long source) {return static_cast(source);} + static T from(long long ) {CAMP_ERROR(camp::BadType(camp::userType, camp::intType));} static T from(double source) {return static_cast(source);} static T from(const std::string& source) {return boost::lexical_cast(source);} static T from(const camp::EnumObject& source) {return static_cast(source.value());} @@ -198,16 +203,19 @@ struct ValueMapper::value * Specialization of ValueMapper for reals */ template -struct ValueMapper::value - && !boost::is_const::value // to avoid conflict with ValueMapper - && !boost::is_reference::value // to avoid conflict with ValueMapper - >::type> +struct ValueMapper::value + && !std::is_const::value // to avoid conflict with ValueMapper + && !std::is_reference::value // to avoid conflict with ValueMapper + >::type> { static const int type = camp::realType; static double to(T source) {return static_cast(source);} static T from(bool source) {return static_cast(source);} + static T from(int source) {return static_cast(source);} static T from(long source) {return static_cast(source);} + static T from(long long source) {return static_cast(source);} + static T from(float source) {return static_cast(source);} static T from(double source) {return static_cast(source);} static T from(const std::string& source) {return boost::lexical_cast(source);} static T from(const camp::EnumObject& source) {return static_cast(source.value());} @@ -224,7 +232,9 @@ struct ValueMapper static const std::string& to(const std::string& source) {return source;} static std::string from(bool source) {return boost::lexical_cast(source);} + static std::string from(int source) {return boost::lexical_cast(source);} static std::string from(long source) {return boost::lexical_cast(source);} + static std::string from(long long source) {return boost::lexical_cast(source);} static std::string from(double source) {return boost::lexical_cast(source);} static std::string from(const std::string& source) {return source;} static std::string from(const camp::EnumObject& source) {return source.name();} @@ -238,10 +248,10 @@ struct ValueMapper * Warning: special case for char[] and const char[], they are strings not arrays */ template -struct ValueMapper::value - && !boost::is_same::ElementType, char>::value - && !boost::is_same::ElementType, const char>::value - >::type> +struct ValueMapper::value + && !std::is_same::ElementType, char>::value + && !std::is_same::ElementType, const char>::value + >::type> { static const int type = camp::arrayType; }; @@ -267,16 +277,18 @@ struct ValueMapper * Specialization of ValueMapper for enum types */ template -struct ValueMapper::value - && !boost::is_const::value // to avoid conflict with ValueMapper - && !boost::is_reference::value // to avoid conflict with ValueMapper - >::type> +struct ValueMapper::value + && !std::is_const::value // to avoid conflict with ValueMapper + && !std::is_reference::value // to avoid conflict with ValueMapper + >::type> { static const int type = camp::enumType; static camp::EnumObject to(T source) {return camp::EnumObject(source);} static T from(bool source) {return static_cast(static_cast(source));} + static T from(int source) {return static_cast(source);} static T from(long source) {return static_cast(source);} + static T from(long long source) {return static_cast(source);} static T from(double source) {return static_cast(static_cast(source));} static T from(const camp::EnumObject& source) {return static_cast(source.value());} static T from(const camp::UserObject&) {CAMP_ERROR(camp::BadType(camp::userType, camp::enumType));} @@ -312,11 +324,13 @@ struct ValueMapper static const camp::EnumObject& to(const camp::EnumObject& source) {return source;} static const camp::EnumObject& from(const camp::EnumObject& source) {return source;} - static camp::UserObject from(bool) {CAMP_ERROR(camp::BadType(camp::boolType, camp::enumType));} - static camp::UserObject from(long) {CAMP_ERROR(camp::BadType(camp::intType, camp::enumType));} - static camp::UserObject from(double) {CAMP_ERROR(camp::BadType(camp::realType, camp::enumType));} - static camp::UserObject from(const std::string&) {CAMP_ERROR(camp::BadType(camp::stringType, camp::enumType));} - static camp::UserObject from(const camp::UserObject&) {CAMP_ERROR(camp::BadType(camp::enumType, camp::enumType));} + static camp::UserObject from(bool) {CAMP_ERROR(camp::BadType(camp::boolType, camp::enumType));} + static camp::UserObject from(int) {CAMP_ERROR(camp::BadType(camp::intType, camp::enumType));} + static camp::UserObject from(long) {CAMP_ERROR(camp::BadType(camp::intType, camp::enumType));} + static camp::UserObject from(long long) {CAMP_ERROR(camp::BadType(camp::intType, camp::enumType));} + static camp::UserObject from(double) {CAMP_ERROR(camp::BadType(camp::realType, camp::enumType));} + static camp::UserObject from(const std::string&) {CAMP_ERROR(camp::BadType(camp::stringType, camp::enumType));} + static camp::UserObject from(const camp::UserObject&) {CAMP_ERROR(camp::BadType(camp::enumType, camp::enumType));} }; /* @@ -329,11 +343,13 @@ struct ValueMapper static const camp::UserObject& to(const camp::UserObject& source) {return source;} static const camp::UserObject& from(const camp::UserObject& source) {return source;} - static camp::UserObject from(bool) {CAMP_ERROR(camp::BadType(camp::boolType, camp::userType));} - static camp::UserObject from(long) {CAMP_ERROR(camp::BadType(camp::intType, camp::userType));} - static camp::UserObject from(double) {CAMP_ERROR(camp::BadType(camp::realType, camp::userType));} - static camp::UserObject from(const std::string&) {CAMP_ERROR(camp::BadType(camp::stringType, camp::userType));} - static camp::UserObject from(const camp::EnumObject&) {CAMP_ERROR(camp::BadType(camp::enumType, camp::userType));} + static camp::UserObject from(bool) {CAMP_ERROR(camp::BadType(camp::boolType, camp::userType));} + static camp::UserObject from(int) {CAMP_ERROR(camp::BadType(camp::intType, camp::userType));} + static camp::UserObject from(long) {CAMP_ERROR(camp::BadType(camp::intType, camp::userType));} + static camp::UserObject from(long long) {CAMP_ERROR(camp::BadType(camp::intType, camp::userType));} + static camp::UserObject from(double) {CAMP_ERROR(camp::BadType(camp::realType, camp::userType));} + static camp::UserObject from(const std::string&) {CAMP_ERROR(camp::BadType(camp::stringType, camp::userType));} + static camp::UserObject from(const camp::EnumObject&) {CAMP_ERROR(camp::BadType(camp::enumType, camp::userType));} }; /* diff --git a/test/arrayproperty.hpp b/test/arrayproperty.hpp index b2ae921..3fa1d02 100644 --- a/test/arrayproperty.hpp +++ b/test/arrayproperty.hpp @@ -13,10 +13,10 @@ ** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell ** copies of the Software, and to permit persons to whom the Software is ** furnished to do so, subject to the following conditions: -** +** ** The above copyright notice and this permission notice shall be included in ** all copies or substantial portions of the Software. -** +** ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -32,7 +32,7 @@ #include #include -#include +#include #include #include @@ -76,7 +76,7 @@ namespace ArrayPropertyTest } bool bools[2]; - boost::array ints; + std::array ints; std::vector strings; std::list objects; }; diff --git a/test/qt/propertymapping.cpp b/test/qt/propertymapping.cpp index 817b565..8f36000 100644 --- a/test/qt/propertymapping.cpp +++ b/test/qt/propertymapping.cpp @@ -13,10 +13,10 @@ ** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell ** copies of the Software, and to permit persons to whom the Software is ** furnished to do so, subject to the following conditions: -** +** ** The above copyright notice and this permission notice shall be included in ** all copies or substantial portions of the Software. -** +** ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -32,6 +32,8 @@ #include #include +#include + using namespace PropertyMappingTest; //----------------------------------------------------------------------------- @@ -43,7 +45,7 @@ struct PropertyMappingFixture object.setBool(true); object.setInt(-10); - object.setULong(20); + object.setULong(std::numeric_limits::max() - 1); object.setDouble(0.55); object.setString("hello"); object.setEnum(MyClass::two); @@ -91,7 +93,7 @@ BOOST_AUTO_TEST_CASE(get) { BOOST_CHECK_EQUAL(metaclass->property("m_bool_read").get(object).to(), true); BOOST_CHECK_EQUAL(metaclass->property("m_int_read").get(object).to(), -10); - BOOST_CHECK_EQUAL(metaclass->property("m_ulong_read").get(object).to(), 20); + BOOST_CHECK_EQUAL(metaclass->property("m_ulong_read").get(object).to(), std::numeric_limits::max() - 1); BOOST_CHECK_CLOSE(metaclass->property("m_double_read").get(object).to(), 0.55, 1E-5); BOOST_CHECK_EQUAL(metaclass->property("m_string_read").get(object).to(), "hello"); BOOST_CHECK_EQUAL(metaclass->property("m_enum_read").get(object).to(), MyClass::two); @@ -102,14 +104,14 @@ BOOST_AUTO_TEST_CASE(set) { metaclass->property("m_bool").set(object, false); metaclass->property("m_int").set(object, -2); - metaclass->property("m_ulong").set(object, 50); + metaclass->property("m_ulong").set(object, std::numeric_limits::max() - 1); metaclass->property("m_double").set(object, -8.8); metaclass->property("m_string").set(object, "bonjour"); metaclass->property("m_enum").set(object, MyClass::three); BOOST_CHECK_EQUAL(metaclass->property("m_bool").get(object).to(), false); BOOST_CHECK_EQUAL(metaclass->property("m_int").get(object).to(), -2); - BOOST_CHECK_EQUAL(metaclass->property("m_ulong").get(object).to(), 50); + BOOST_CHECK_EQUAL(metaclass->property("m_ulong").get(object).to(), std::numeric_limits::max() - 1); BOOST_CHECK_CLOSE(metaclass->property("m_double").get(object).to(), -8.8, 1E-5); BOOST_CHECK_EQUAL(metaclass->property("m_string").get(object).to(), "bonjour"); BOOST_CHECK_EQUAL(metaclass->property("m_enum").get(object).to(), MyClass::three);