* Updated project structuremaster
| @@ -1,3 +1,3 @@ | |||
| [submodule "cmake/modules"] | |||
| path = cmake/modules | |||
| url = https://git.bergmann89.de/cpp/CmakeModules.git | |||
| url = b3rgmann@git.bergmann89.de:cpp/CMakeModules.git | |||
| @@ -1,63 +1,63 @@ | |||
| # Initialize CMake ################################################################################ | |||
| CMake_Minimum_Required ( VERSION 3.12.0 FATAL_ERROR ) | |||
| CMake_Minimum_Required ( VERSION 3.12.0 FATAL_ERROR ) | |||
| # Set CMAKE_BUILD_TYPE | |||
| If ( NOT CMAKE_BUILD_TYPE ) | |||
| Set ( CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build!" FORCE ) | |||
| EndIf ( NOT CMAKE_BUILD_TYPE ) | |||
| Set_Property ( CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS Debug Release RelWithDebInfo MinSizeRel ) | |||
| If ( NOT CMAKE_BUILD_TYPE ) | |||
| Set ( CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build!" FORCE ) | |||
| EndIf ( NOT CMAKE_BUILD_TYPE ) | |||
| Set_Property ( CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS Debug Release RelWithDebInfo MinSizeRel ) | |||
| # Set CMAKE_MODULE_PATH | |||
| If ( EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/cmake/" ) | |||
| Set ( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} | |||
| "${CMAKE_CURRENT_SOURCE_DIR}/cmake/" ) | |||
| EndIf ( ) | |||
| If ( EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/cmake/" ) | |||
| Set ( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} | |||
| "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules" ) | |||
| EndIf ( ) | |||
| If ( EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/cmake/" ) | |||
| Set ( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} | |||
| "${CMAKE_CURRENT_SOURCE_DIR}/cmake/" ) | |||
| EndIf ( ) | |||
| If ( EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules/cmake" ) | |||
| Set ( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} | |||
| "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules/cmake" ) | |||
| EndIf ( ) | |||
| # Project ######################################################################################### | |||
| Include ( GNUInstallDirs ) | |||
| Include ( ${CMAKE_CURRENT_SOURCE_DIR}/cmake/cpprtti-options.cmake ) | |||
| Include ( ${CMAKE_CURRENT_SOURCE_DIR}/cmake/cpprtti-const.cmake ) | |||
| Include ( ${CMAKE_CURRENT_SOURCE_DIR}/cmake/cpprtti-var.cmake ) | |||
| Project ( ${CPPRTTI_PROJECT_NAME} | |||
| DESCRIPTION "${CPPRTTI_PROJECT_DESCRIPTION}" | |||
| VERSION "${CPPRTTI_VERSION}" ) | |||
| Include ( CTest ) | |||
| Include ( GNUInstallDirs ) | |||
| Include ( ${CMAKE_CURRENT_SOURCE_DIR}/cmake/cpprtti-options.cmake ) | |||
| Include ( ${CMAKE_CURRENT_SOURCE_DIR}/cmake/cpprtti-const.cmake ) | |||
| Include ( ${CMAKE_CURRENT_SOURCE_DIR}/cmake/cpprtti-var.cmake ) | |||
| Project ( ${CPPRTTI_PROJECT_NAME} | |||
| DESCRIPTION "${CPPRTTI_PROJECT_DESCRIPTION}" | |||
| VERSION "${CPPRTTI_VERSION}" ) | |||
| Include ( CTest ) | |||
| # Subdirectories | |||
| Add_SubDirectory ( ${CMAKE_CURRENT_SOURCE_DIR}/src ) | |||
| Add_SubDirectory ( ${CMAKE_CURRENT_SOURCE_DIR}/test ) | |||
| Add_SubDirectory ( ${CMAKE_CURRENT_SOURCE_DIR}/src ) | |||
| Add_SubDirectory ( ${CMAKE_CURRENT_SOURCE_DIR}/test ) | |||
| # Install | |||
| If ( NOT CPPRTTI_HAS_EXPORT | |||
| OR NOT CPPRTTI_INSTALL_PACKAGE ) | |||
| Return ( ) | |||
| EndIf ( ) | |||
| Include ( CMakePackageConfigHelpers ) | |||
| Write_Basic_Package_Version_File ( "${CMAKE_CURRENT_BINARY_DIR}/cmake/cpprtti-config-version.cmake" | |||
| VERSION ${CPPRTTI_VERSION} | |||
| COMPATIBILITY AnyNewerVersion ) | |||
| Configure_File ( "${CMAKE_CURRENT_SOURCE_DIR}/cmake/cpprtti-config.cmake" | |||
| "${CMAKE_CURRENT_BINARY_DIR}/cmake/cpprtti-config.cmake" | |||
| @ONLY ) | |||
| Set ( ConfigPackageLocation "${CPPRTTI_INSTALL_DIR_SHARE}/cmake" ) | |||
| Install ( EXPORT | |||
| cpprtti | |||
| NAMESPACE | |||
| cpprtti:: | |||
| DESTINATION | |||
| ${ConfigPackageLocation} ) | |||
| Install ( FILES | |||
| If ( NOT CPPRTTI_HAS_EXPORT | |||
| OR NOT CPPRTTI_INSTALL_PACKAGE ) | |||
| Return ( ) | |||
| EndIf ( ) | |||
| Include ( CMakePackageConfigHelpers ) | |||
| Write_Basic_Package_Version_File ( "${CMAKE_CURRENT_BINARY_DIR}/cmake/cpprtti-config-version.cmake" | |||
| VERSION ${CPPRTTI_VERSION} | |||
| COMPATIBILITY AnyNewerVersion ) | |||
| Configure_File ( "${CMAKE_CURRENT_SOURCE_DIR}/cmake/cpprtti-config.cmake" | |||
| "${CMAKE_CURRENT_BINARY_DIR}/cmake/cpprtti-config.cmake" | |||
| "${CMAKE_CURRENT_BINARY_DIR}/cmake/cpprtti-config-version.cmake" | |||
| DESTINATION | |||
| ${ConfigPackageLocation} | |||
| COMPONENT | |||
| Devel ) | |||
| @ONLY ) | |||
| Set ( ConfigPackageLocation "${CPPRTTI_INSTALL_DIR_SHARE}/cmake" ) | |||
| Install ( EXPORT | |||
| cpprtti | |||
| NAMESPACE | |||
| cpprtti:: | |||
| DESTINATION | |||
| ${ConfigPackageLocation} ) | |||
| Install ( FILES | |||
| "${CMAKE_CURRENT_BINARY_DIR}/cmake/cpprtti-config.cmake" | |||
| "${CMAKE_CURRENT_BINARY_DIR}/cmake/cpprtti-config-version.cmake" | |||
| DESTINATION | |||
| ${ConfigPackageLocation} | |||
| COMPONENT | |||
| Devel ) | |||
| @@ -0,0 +1,3 @@ | |||
| # cpprtti | |||
| C++ run time type information library. | |||
| @@ -25,7 +25,7 @@ If ( NOT ${CHECKOUT_RET} EQUAL 0 ) | |||
| EndIf ( ) | |||
| # Include Cloned Repository | |||
| Include ( ${CMAKE_CURRENT_LIST_DIR}/modules/find_local_module.cmake ) | |||
| Include ( ${CMAKE_CURRENT_LIST_DIR}/modules/cmake/find_local_module.cmake ) | |||
| FindLocalModule ( cppcore ${CPPCORE_CHECKOUT_DIR} ) | |||
| # Create Alias Targets | |||
| @@ -25,7 +25,7 @@ If ( NOT ${CHECKOUT_RET} EQUAL 0 ) | |||
| EndIf ( ) | |||
| # Include Cloned Repository | |||
| Include ( ${CMAKE_CURRENT_LIST_DIR}/modules/find_local_module.cmake ) | |||
| Include ( ${CMAKE_CURRENT_LIST_DIR}/modules/cmake/find_local_module.cmake ) | |||
| FindLocalModule ( cppmp ${CPPMP_CHECKOUT_DIR} ) | |||
| # Create Alias Targets | |||
| @@ -1,28 +1,28 @@ | |||
| # This file contains constant variables that are fixed to this project | |||
| # Version | |||
| Set ( CPPRTTI_VERSION_MAJOR 1 ) | |||
| Set ( CPPRTTI_VERSION_MINOR 0 ) | |||
| Set ( CPPRTTI_VERSION_PATCH 0 ) | |||
| Set ( CPPRTTI_VERSION_BUILD 0 ) | |||
| Set ( CPPRTTI_VERSION_HASH "" ) | |||
| Set ( CPPRTTI_VERSION_BEHIND 0 ) | |||
| Set ( CPPRTTI_VERSION_DIRTY 0 ) | |||
| Set ( CPPRTTI_VERSION_MAJOR 1 ) | |||
| Set ( CPPRTTI_VERSION_MINOR 0 ) | |||
| Set ( CPPRTTI_VERSION_PATCH 0 ) | |||
| Set ( CPPRTTI_VERSION_BUILD 0 ) | |||
| Set ( CPPRTTI_VERSION_HASH "" ) | |||
| Set ( CPPRTTI_VERSION_BEHIND 0 ) | |||
| Set ( CPPRTTI_VERSION_DIRTY 0 ) | |||
| # Names | |||
| Set ( CPPRTTI_PROJECT_NAME "cpprtti" ) | |||
| Set ( CPPRTTI_PROJECT_DESCRIPTION "A simple hello world library" ) | |||
| Set ( CPPRTTI_PROJECT_NAME "cpprtti" ) | |||
| Set ( CPPRTTI_PROJECT_DESCRIPTION "C++ run time type information library" ) | |||
| # Include generated variables for further usage | |||
| Include ( ${CMAKE_CURRENT_LIST_DIR}/cpprtti-var.cmake ) | |||
| Include ( ${CMAKE_CURRENT_LIST_DIR}/cpprtti-var.cmake ) | |||
| # Install directories | |||
| Set ( CPPRTTI_INSTALL_DIR_INCLUDE "${CMAKE_INSTALL_INCLUDEDIR}/${CPPRTTI_NAME}" ) | |||
| Set ( CPPRTTI_INSTALL_DIR_LIB "${CMAKE_INSTALL_LIBDIR}" ) | |||
| Set ( CPPRTTI_INSTALL_DIR_SHARE "${CMAKE_INSTALL_DATAROOTDIR}/${CPPRTTI_NAME}" ) | |||
| Set ( CPPRTTI_INSTALL_DIR_INCLUDE "${CMAKE_INSTALL_INCLUDEDIR}/${CPPRTTI_NAME}" ) | |||
| Set ( CPPRTTI_INSTALL_DIR_LIB "${CMAKE_INSTALL_LIBDIR}" ) | |||
| Set ( CPPRTTI_INSTALL_DIR_SHARE "${CMAKE_INSTALL_DATAROOTDIR}/${CPPRTTI_NAME}" ) | |||
| # C Standard | |||
| Set ( CMAKE_C_STANDARD 11 ) | |||
| Set ( CMAKE_CXX_STANDARD 17 ) | |||
| Set ( CMAKE_C_STANDARD_REQUIRED ON ) | |||
| Set ( CMAKE_CXX_STANDARD_REQUIRED ON ) | |||
| Set ( CMAKE_C_STANDARD 11 ) | |||
| Set ( CMAKE_CXX_STANDARD 17 ) | |||
| Set ( CMAKE_C_STANDARD_REQUIRED ON ) | |||
| Set ( CMAKE_CXX_STANDARD_REQUIRED ON ) | |||
| @@ -1,23 +1,11 @@ | |||
| # This file contains options that can be passed to the cmake command | |||
| Option ( CPPRTTI_INSTALL_HEADER | |||
| "Install headers of cpprtti." | |||
| ON ) | |||
| Option ( CPPRTTI_INSTALL_STATIC | |||
| "Install static library of cpprtti." | |||
| ON ) | |||
| Option ( CPPRTTI_INSTALL_SHARED | |||
| "Install shared library of cpprtti." | |||
| ON ) | |||
| Option ( CPPRTTI_INSTALL_DEBUG | |||
| "Install the stripped debug informations of cpprtti." | |||
| OFF ) | |||
| Option ( CPPRTTI_INSTALL_PACKAGE | |||
| "Install the cmake package of cpprtti." | |||
| ON ) | |||
| Option ( CPPRTTI_NO_STRIP | |||
| "Do not strip debug symbols from binary." | |||
| OFF ) | |||
| Option ( CPPRTTI_USE_GIT_VERSION | |||
| "Read the git tags to get the version of cpprtti" | |||
| ON ) | |||
| Option ( CPPRTTI_INSTALL_HEADER | |||
| "Install headers of cpprtti." | |||
| ON ) | |||
| Option ( CPPRTTI_INSTALL_PACKAGE | |||
| "Install the cmake package of cpprtti." | |||
| ON ) | |||
| Option ( CPPRTTI_USE_GIT_VERSION | |||
| "Read the git tags to get the version of cpprtti" | |||
| ON ) | |||
| @@ -1,26 +1,32 @@ | |||
| # This file contains generated variables that are needed for the project | |||
| # Git Version | |||
| If ( CPPRTTI_USE_GIT_VERSION ) | |||
| Include ( git_helper OPTIONAL RESULT_VARIABLE HAS_GIT_HELPER ) | |||
| If ( HAS_GIT_HELPER ) | |||
| GitGetVersion ( ${CMAKE_CURRENT_LIST_DIR}/.. | |||
| CPPRTTI_VERSION_MAJOR | |||
| CPPRTTI_VERSION_MINOR | |||
| CPPRTTI_VERSION_PATCH | |||
| CPPRTTI_VERSION_BUILD | |||
| CPPRTTI_VERSION_HASH | |||
| CPPRTTI_VERSION_BEHIND | |||
| CPPRTTI_VERSION_DIRTY ) | |||
| EndIf ( ) | |||
| EndIf ( ) | |||
| If ( CPPRTTI_USE_GIT_VERSION ) | |||
| Include ( git_helper OPTIONAL RESULT_VARIABLE HAS_GIT_HELPER ) | |||
| If ( HAS_GIT_HELPER ) | |||
| GitGetVersion ( ${CMAKE_CURRENT_LIST_DIR}/.. | |||
| CPPRTTI_VERSION_MAJOR | |||
| CPPRTTI_VERSION_MINOR | |||
| CPPRTTI_VERSION_PATCH | |||
| CPPRTTI_VERSION_BUILD | |||
| CPPRTTI_VERSION_HASH | |||
| CPPRTTI_VERSION_BEHIND | |||
| CPPRTTI_VERSION_DIRTY ) | |||
| EndIf ( ) | |||
| EndIf ( ) | |||
| # Strings | |||
| Set ( CPPRTTI_VERSION_SHORT "${CPPRTTI_VERSION_MAJOR}.${CPPRTTI_VERSION_MINOR}" ) | |||
| Set ( CPPRTTI_VERSION "${CPPRTTI_VERSION_SHORT}.${CPPRTTI_VERSION_PATCH}.${CPPRTTI_VERSION_BUILD}" ) | |||
| Set ( CPPRTTI_VERSION_COMPLETE "${CPPRTTI_VERSION}" ) | |||
| Set ( CPPRTTI_NAME "${CPPRTTI_PROJECT_NAME}-${CPPRTTI_VERSION_SHORT}" ) | |||
| Set ( CPPRTTI_OUTPUTNAME "${CPPRTTI_PROJECT_NAME}" ) | |||
| If ( CPPRTTI_VERSION_BEHIND ) | |||
| Set ( CPPRTTI_VERSION_COMPLETE "${CPPRTTI_VERSION_COMPLETE}+${CPPRTTI_VERSION_BEHIND}" ) | |||
| EndIf ( ) | |||
| Set ( CPPRTTI_VERSION_SHORT | |||
| "${CPPRTTI_VERSION_MAJOR}.${CPPRTTI_VERSION_MINOR}" ) | |||
| Set ( CPPRTTI_VERSION | |||
| "${CPPRTTI_VERSION_SHORT}.${CPPRTTI_VERSION_PATCH}.${CPPRTTI_VERSION_BUILD}" ) | |||
| Set ( CPPRTTI_VERSION_COMPLETE | |||
| "${CPPRTTI_VERSION}" ) | |||
| Set ( CPPRTTI_NAME | |||
| "${CPPRTTI_PROJECT_NAME}-${CPPRTTI_VERSION_SHORT}" ) | |||
| Set ( CPPRTTI_OUTPUTNAME | |||
| "${CPPRTTI_PROJECT_NAME}" ) | |||
| If ( CPPRTTI_VERSION_BEHIND ) | |||
| Set ( CPPRTTI_VERSION_COMPLETE | |||
| "${CPPRTTI_VERSION_COMPLETE}+${CPPRTTI_VERSION_BEHIND}" ) | |||
| EndIf ( ) | |||
| @@ -1 +1 @@ | |||
| Subproject commit ebbae4fbb42d671331b4c6e9d1d142f41dcacc1b | |||
| Subproject commit 94b9877d65e46c9d8169ebc46f163d02e4d9dcf3 | |||
| @@ -4,3 +4,5 @@ | |||
| #include <cpprtti/registry.h> | |||
| #include <cpprtti/traits.h> | |||
| #include <cpprtti/types.h> | |||
| #include <cpprtti/registry.inl> | |||
| @@ -2,8 +2,10 @@ | |||
| #include "misc/exception.h" | |||
| #include "misc/helper.h" | |||
| #include "misc/storage.h" | |||
| #include "misc/variant.h" | |||
| #include "misc/exception.inl" | |||
| #include "misc/helper.inl" | |||
| #include "misc/storage.inl" | |||
| #include "misc/variant.inl" | |||
| @@ -23,11 +23,15 @@ namespace cpprtti | |||
| /* variant */ | |||
| variant_error = 2000, | |||
| variant_is_empty, //!< The variant does not store any value! | |||
| variant_is_const, //!< The value stored in the variant is const! | |||
| variant_type_mismatch, //!< The variant does not store the requested type! | |||
| variant_invalid_cast, //!< The value stored in the variant could not be cast to the requested type! | |||
| variant_convert_to, //!< No known conversion for the passed types. | |||
| variant_assign, //!< Variant is not copy assignable. | |||
| /* class */ | |||
| class_error = 3000, | |||
| class_member_does_not_exist, //!< The requested member does not exist. | |||
| class_member_already_exists, //!< Unable to create member: Name is already in use! | |||
| class_type_mismatch, //!< Type does not match the. | |||
| class_member_not_readable, //!< Member variable is not readable! | |||
| @@ -72,5 +76,3 @@ namespace cpprtti | |||
| }; | |||
| } | |||
| #include "exception.inl" | |||
| @@ -7,6 +7,13 @@ namespace cpprtti | |||
| { | |||
| using type_id = size_t; | |||
| using storage_id = size_t; | |||
| /** | |||
| * @brief Get the ID of a certain C++ storage class. | |||
| */ | |||
| template<typename X> | |||
| inline storage_id get_storage_id(); | |||
| /** | |||
| * @brief Get the ID of a certain C++ type. | |||
| @@ -21,5 +28,3 @@ namespace cpprtti | |||
| inline const std::string& get_type_name(); | |||
| } | |||
| #include "helper.inl" | |||
| @@ -10,7 +10,11 @@ namespace cpprtti | |||
| namespace __impl | |||
| { | |||
| inline type_id create_type_id() | |||
| struct tag_type_id { }; | |||
| struct tag_storage_id { }; | |||
| template<typename...> | |||
| inline type_id create_id() | |||
| { | |||
| static type_id value { }; | |||
| return ++value; | |||
| @@ -26,10 +30,19 @@ namespace cpprtti | |||
| } | |||
| template<typename X> | |||
| storage_id get_storage_id() | |||
| { | |||
| using namespace __impl; | |||
| static const auto value = create_id<tag_storage_id>(); | |||
| return value; | |||
| } | |||
| template<typename X> | |||
| type_id get_type_id() | |||
| { | |||
| static const auto value = __impl::create_type_id(); | |||
| using namespace __impl; | |||
| static const auto value = create_id<tag_type_id>(); | |||
| return value; | |||
| } | |||
| @@ -0,0 +1,46 @@ | |||
| #pragma once | |||
| #include <memory> | |||
| #include <vector> | |||
| #include "helper.h" | |||
| namespace cpprtti | |||
| { | |||
| struct storage_container | |||
| { | |||
| private: | |||
| using item_ptr_s = std::shared_ptr<void>; | |||
| using item_vector = std::vector<item_ptr_s>; | |||
| private: | |||
| item_vector _items; | |||
| public: | |||
| /** | |||
| * @brief Get the requested storage or nullptr if the storage does not exist. | |||
| */ | |||
| template<typename T> | |||
| T* storage(); | |||
| /** | |||
| * @brief Get the requested storage or nullptr if the storage does not exist. | |||
| */ | |||
| template<typename T> | |||
| T* storage(bool can_create); | |||
| /** | |||
| * @brief Create a new storage. | |||
| */ | |||
| template<typename T> | |||
| T* storage(const std::shared_ptr<T>& item); | |||
| /** | |||
| * @brief Get the requested storage or nullptr if the storage does not exist. | |||
| */ | |||
| template<typename T> | |||
| const T* storage() const; | |||
| }; | |||
| } | |||
| @@ -0,0 +1,61 @@ | |||
| #pragma once | |||
| #include <cppmp/core/modifier.h> | |||
| #include "storage.h" | |||
| namespace cpprtti | |||
| { | |||
| /* storage_container */ | |||
| template<typename T> | |||
| T* storage_container::storage() | |||
| { | |||
| using storage_type = cppmp::decay_t<T>; | |||
| auto id = get_storage_id<storage_type>(); | |||
| return (id < _items.size()) | |||
| ? static_cast<storage_type*>(_items[id].get()) | |||
| : nullptr; | |||
| } | |||
| template<typename T> | |||
| T* storage_container::storage(bool can_create) | |||
| { | |||
| using storage_type = cppmp::decay_t<T>; | |||
| auto id = get_storage_id<storage_type>(); | |||
| if ( can_create | |||
| && ( id >= _items.size() | |||
| || !_items[id])) | |||
| { | |||
| _items.resize(id + 1); | |||
| _items[id] = std::make_shared<storage_type>(); | |||
| } | |||
| return (id < _items.size()) | |||
| ? static_cast<storage_type*>(_items[id].get()) | |||
| : nullptr; | |||
| } | |||
| template<typename T> | |||
| T* storage_container::storage(const std::shared_ptr<T>& item) | |||
| { | |||
| using storage_type = cppmp::decay_t<T>; | |||
| auto id = get_storage_id<storage_type>(); | |||
| _items.resize(id + 1); | |||
| _items[id] = item; | |||
| return (id < _items.size()) | |||
| ? static_cast<storage_type*>(_items[id].get()) | |||
| : nullptr; | |||
| } | |||
| template<typename T> | |||
| const T* storage_container::storage() const | |||
| { | |||
| using storage_type = cppmp::decay_t<T>; | |||
| auto id = get_storage_id<storage_type>(); | |||
| return (id < _items.size()) | |||
| ? static_cast<storage_type*>(_items[id].get()) | |||
| : nullptr; | |||
| } | |||
| } | |||
| @@ -5,11 +5,13 @@ | |||
| #include <cppmp/misc/generic_predicate.h> | |||
| #include "helper.h" | |||
| #include "../types/type.h" | |||
| namespace cpprtti | |||
| { | |||
| struct type; | |||
| struct variant; | |||
| namespace __impl | |||
| { | |||
| @@ -22,18 +24,36 @@ namespace cpprtti | |||
| struct variant_impl | |||
| { | |||
| public: | |||
| const type& type; | |||
| void * data { nullptr }; | |||
| bool is_const { false }; | |||
| bool is_reference { false }; | |||
| public: | |||
| /** | |||
| * @brief Constructor. | |||
| */ | |||
| inline variant_impl(const cpprtti::type& p_type); | |||
| /** | |||
| * @brief Destructor. | |||
| */ | |||
| virtual ~variant_impl() = default; | |||
| /** | |||
| * @brief Assign a new value. | |||
| */ | |||
| inline void assign(const variant& v); | |||
| private: | |||
| /** | |||
| * @brief Actual implementation of the assign method. | |||
| */ | |||
| virtual void assign_impl(const variant& v) = 0; | |||
| }; | |||
| using variant_impl_ptr_s = std::shared_ptr<const variant_impl>; | |||
| using variant_impl_ptr_s = std::shared_ptr<variant_impl>; | |||
| } | |||
| @@ -81,7 +101,23 @@ namespace cpprtti | |||
| /** | |||
| * @brief Check if the variant contains a value. | |||
| */ | |||
| inline bool empty(); | |||
| inline bool empty() const; | |||
| /** | |||
| * @brief Convert this variant to another type. | |||
| */ | |||
| template<typename T_to> | |||
| inline variant to() const; | |||
| /** | |||
| * @brief Convert this variant to another type. | |||
| */ | |||
| inline variant to(const cpprtti::type& t) const; | |||
| /** | |||
| * @brief Assign the value of this variant from another variant. | |||
| */ | |||
| inline void assign(const variant& v); | |||
| /** | |||
| * @brief Check if the variant contains a value. | |||
| @@ -98,5 +134,3 @@ namespace cpprtti | |||
| constexpr decltype(auto) make_variant = cppmp::generic_predicate<__impl::variant_builder> { }; | |||
| } | |||
| #include "variant.inl" | |||
| @@ -2,6 +2,7 @@ | |||
| #include <cppcore/misc/string_builder.h> | |||
| #include <cppmp/core/types.h> | |||
| #include <cppmp/core/checker.h> | |||
| #include <cppmp/core/modifier.h> | |||
| #include <cppmp/core/conditionals.h> | |||
| @@ -24,6 +25,44 @@ namespace cpprtti | |||
| : type(p_type) | |||
| { } | |||
| void variant_impl::assign(const variant& v) | |||
| { | |||
| if (is_const) | |||
| { | |||
| throw exception( | |||
| error_code::variant_is_const, | |||
| "The value stored in the variant is const!"); | |||
| } | |||
| if (v.empty()) | |||
| { | |||
| throw exception( | |||
| error_code::variant_is_empty, | |||
| "The passed variant does not store any value!"); | |||
| } | |||
| if (type.id() != v.type().id()) | |||
| { | |||
| auto converter = v.type().convert_to(type.id()); | |||
| if (!converter) | |||
| { | |||
| throw exception( | |||
| error_code::variant_convert_to, | |||
| cppcore::string_builder() | |||
| << "No known conversion from type '" | |||
| << v.type().name() | |||
| << "' to type '" | |||
| << type.name() | |||
| << "'!"); | |||
| } | |||
| this->assign_impl((*converter)(v)); | |||
| } | |||
| else | |||
| { | |||
| this->assign_impl(v); | |||
| } | |||
| } | |||
| /* variant_builder - default */ | |||
| template<typename X, typename> | |||
| @@ -61,6 +100,11 @@ namespace cpprtti | |||
| is_const = cppmp::is_const_v<cppmp::remove_reference_t<T>>; | |||
| is_reference = false; | |||
| } | |||
| void assign_impl(const variant& v) override | |||
| { | |||
| *static_cast<cppmp::decay_t<T>*>(data) = v.get<const T&>(); | |||
| }; | |||
| }; | |||
| template<typename X_registry, typename X> | |||
| @@ -94,6 +138,30 @@ namespace cpprtti | |||
| is_const = cppmp::is_const_v<cppmp::remove_reference_t<T>>; | |||
| is_reference = true; | |||
| } | |||
| void assign_impl(const variant& v) override | |||
| { | |||
| }; | |||
| template<typename X = cppmp::decay_t<T>> | |||
| cppmp::enable_if_t<cppmp::is_copy_assignable_v<X>> | |||
| assign_helper(const variant& v) | |||
| { | |||
| *static_cast<cppmp::decay_t<T>*>(data) = v.get<const T&>(); | |||
| } | |||
| template<typename X = cppmp::decay_t<T>> | |||
| cppmp::enable_if_t<!cppmp::is_copy_assignable_v<X>> | |||
| assign_helper(const variant& v) | |||
| { | |||
| throw exception( | |||
| error_code::variant_assign, | |||
| cppcore::string_builder() | |||
| << "Value of type '" | |||
| << type.name() | |||
| << "' is not copy assignable!"); | |||
| } | |||
| }; | |||
| template<typename X_registry, typename X> | |||
| @@ -121,6 +189,19 @@ namespace cpprtti | |||
| { return std::forward<X>(x); } | |||
| }; | |||
| /* variant_builder - type, variant (convert_from) */ | |||
| template<typename T_registry, typename... T_args> | |||
| struct variant_builder< | |||
| cppmp::list<T_registry, const type&, T_args...>, | |||
| void | |||
| > | |||
| { | |||
| template<typename X_registry, typename... X_args> | |||
| static constexpr decltype(auto) apply(X_registry& p_registry, const type& t, X_args&&... args) | |||
| { return make_variant(std::forward<X_args>(args)...).to(t.id()); } | |||
| }; | |||
| /* value_extractor - default */ | |||
| template<typename X, typename = void> | |||
| @@ -234,12 +315,50 @@ namespace cpprtti | |||
| << ")"); | |||
| } | |||
| return __impl::extract_value(*_impl, cppmp::type_v<T>); | |||
| auto& impl = static_cast<const __impl::variant_impl&>(*_impl); | |||
| return __impl::extract_value(impl, cppmp::type_v<T>); | |||
| } | |||
| bool variant::empty() | |||
| bool variant::empty() const | |||
| { return !static_cast<bool>(_impl); } | |||
| template<typename T_to> | |||
| variant variant::to() const | |||
| { | |||
| using to_type = cppmp::decay_t<T_to>; | |||
| return to(get_type_id<to_type>()); | |||
| } | |||
| variant variant::to(const cpprtti::type& t) const | |||
| { | |||
| check_impl(); | |||
| auto& type = _impl->type; | |||
| if (t.id() == type.id()) | |||
| return *this; | |||
| auto* converter = type.convert_to(t.id()); | |||
| if (!converter) | |||
| { | |||
| throw exception( | |||
| error_code::variant_is_empty, | |||
| cppcore::string_builder() | |||
| << "No known conversion from type '" | |||
| << type.name() | |||
| << "' to type '" | |||
| << t.name() | |||
| << "'!"); | |||
| } | |||
| return (*converter)(*this); | |||
| } | |||
| inline void variant::assign(const variant& v) | |||
| { | |||
| check_impl(); | |||
| _impl->assign(v); | |||
| } | |||
| variant::operator bool() const | |||
| { return static_cast<bool>(_impl); } | |||
| @@ -4,6 +4,7 @@ | |||
| #include <memory> | |||
| #include "types/type.h" | |||
| #include "types/type_decorator.h" | |||
| namespace cpprtti | |||
| { | |||
| @@ -88,9 +89,7 @@ namespace cpprtti | |||
| * @brief Create a new type for the passed C++ type with the passed implementation type. | |||
| */ | |||
| template<typename T_impl> | |||
| inline T_impl& create(); | |||
| inline type_decorator<T_impl>& create(); | |||
| }; | |||
| } | |||
| #include "registry.inl" | |||
| @@ -18,7 +18,8 @@ namespace cpprtti | |||
| template<typename T_type> | |||
| const auto& registry::get() const | |||
| { | |||
| using impl_type = default_type_t<T_type>; | |||
| using impl_type = default_type_t<T_type>; | |||
| using decorated_type = type_decorator<impl_type>; | |||
| auto * t = find<T_type>(); | |||
| @@ -31,7 +32,7 @@ namespace cpprtti | |||
| << get_type_name<T_type>()); | |||
| } | |||
| auto * ret = dynamic_cast<const impl_type *>(t); | |||
| auto * ret = dynamic_cast<const decorated_type *>(t); | |||
| if (!ret) | |||
| { | |||
| throw exception( | |||
| @@ -47,11 +48,14 @@ namespace cpprtti | |||
| template<typename T_type, typename T_impl> | |||
| auto& registry::get() | |||
| { | |||
| using impl_type = T_impl; | |||
| using decorated_type = type_decorator<impl_type>; | |||
| auto * t = find<T_type>(); | |||
| if (!t) | |||
| t = &create<T_impl>(); | |||
| t = &create<impl_type>(); | |||
| auto * ret = dynamic_cast<T_impl *>(t); | |||
| auto * ret = dynamic_cast<decorated_type *>(t); | |||
| if (!ret) | |||
| { | |||
| throw exception( | |||
| @@ -105,9 +109,11 @@ namespace cpprtti | |||
| } | |||
| template<typename T_impl> | |||
| T_impl& registry::create() | |||
| type_decorator<T_impl>& registry::create() | |||
| { | |||
| auto impl = std::make_shared<T_impl>(*this); | |||
| using decorated_type = type_decorator<T_impl>; | |||
| auto impl = std::make_shared<decorated_type>(*this); | |||
| auto id_it = _id_map.find(impl->id()); | |||
| if (id_it != _id_map.end()) | |||
| @@ -10,5 +10,3 @@ namespace cpprtti | |||
| using default_type_t = typename default_type_trait<cppmp::decay_t<T>>::type; | |||
| } | |||
| #include "default_type.inl" | |||
| @@ -5,10 +5,12 @@ | |||
| #include "types/fundamental_type_tpl.h" | |||
| #include "types/fundamental_type.h" | |||
| #include "types/member.h" | |||
| #include "types/type_decorator.h" | |||
| #include "types/type.h" | |||
| #include "types/class_type_tpl.inl" | |||
| #include "types/class_type.inl" | |||
| #include "types/fundamental_type_tpl.inl" | |||
| #include "types/fundamental_type.inl" | |||
| #include "types/type_decorator.inl" | |||
| #include "types/type.inl" | |||
| @@ -31,13 +31,18 @@ namespace cpprtti | |||
| /** | |||
| * @brief Get a map of all registered members. | |||
| */ | |||
| const member_map& members() const; | |||
| inline const member& member(const std::string& p_name) const; | |||
| /** | |||
| * @brief Get a map of all registered members. | |||
| */ | |||
| inline const member_map& members() const; | |||
| /** | |||
| * @brief Register a new member variable. | |||
| */ | |||
| template<typename... T_args> | |||
| auto& add_member_variable( | |||
| inline auto& add_member_variable( | |||
| const std::string& p_name, | |||
| T_args&&... p_args); | |||
| @@ -45,11 +50,9 @@ namespace cpprtti | |||
| * @brief Register a new member method. | |||
| */ | |||
| template<typename... T_args> | |||
| auto& add_member_method( | |||
| inline auto& add_member_method( | |||
| const std::string& p_name, | |||
| T_args&&... p_args); | |||
| }; | |||
| } | |||
| #include "class_type.inl" | |||
| @@ -16,6 +16,22 @@ namespace cpprtti | |||
| : type(p_registry, p_id, p_name, rtti_type_t::class_type) | |||
| { } | |||
| const member& class_type::member( | |||
| const std::string& p_name) const | |||
| { | |||
| auto it = _members.find(p_name); | |||
| if (it == _members.end()) | |||
| { | |||
| throw exception( | |||
| error_code::class_member_does_not_exist, | |||
| cppcore::string_builder() | |||
| << "Member with the name '" | |||
| << p_name | |||
| << "' does not exists"); | |||
| } | |||
| return *it->second; | |||
| } | |||
| const class_type::member_map& class_type | |||
| ::members() const | |||
| { return _members; } | |||
| @@ -21,5 +21,3 @@ namespace cpprtti | |||
| }; | |||
| } | |||
| #include "class_type_tpl.inl" | |||
| @@ -19,5 +19,3 @@ namespace cpprtti | |||
| }; | |||
| } | |||
| #include "fundamental_type.inl" | |||
| @@ -21,5 +21,3 @@ namespace cpprtti | |||
| }; | |||
| } | |||
| #include "fundamental_type_tpl.inl" | |||
| @@ -3,6 +3,7 @@ | |||
| #include <string> | |||
| #include "../../types/type.h" | |||
| #include "../../misc/storage.h" | |||
| namespace cpprtti | |||
| { | |||
| @@ -15,6 +16,7 @@ namespace cpprtti | |||
| }; | |||
| struct member | |||
| : public storage_container | |||
| { | |||
| protected: | |||
| cpprtti::type& _owner; | |||
| @@ -52,5 +54,3 @@ namespace cpprtti | |||
| }; | |||
| } | |||
| #include "member.inl" | |||
| @@ -3,6 +3,7 @@ | |||
| #include <cppmp/misc/generic_predicate.h> | |||
| #include "member.h" | |||
| #include "../../misc/variant.h" | |||
| namespace cpprtti | |||
| { | |||
| @@ -42,5 +43,3 @@ namespace cpprtti | |||
| constexpr decltype(auto) make_member_method = cppmp::generic_predicate<__impl::member_method_builder> { }; | |||
| } | |||
| #include "member_method.inl" | |||
| @@ -3,6 +3,7 @@ | |||
| #include <cppmp/traits/lambda_traits.h> | |||
| #include "member_method.h" | |||
| #include "../../misc/variant.h" | |||
| namespace cpprtti | |||
| { | |||
| @@ -36,17 +36,17 @@ namespace cpprtti | |||
| /** | |||
| * @brief RTTI type of that member represents. | |||
| */ | |||
| const cpprtti::type& type() const; | |||
| inline const cpprtti::type& type() const; | |||
| /** | |||
| * @brief Check if the variable is readable. | |||
| */ | |||
| bool is_readale() const; | |||
| inline bool is_readale() const; | |||
| /** | |||
| * @brief Check if the variable is writable. | |||
| */ | |||
| bool is_writable() const; | |||
| inline bool is_writable() const; | |||
| /** | |||
| * @brief Get the current value of the member. | |||
| @@ -75,5 +75,3 @@ namespace cpprtti | |||
| constexpr decltype(auto) make_member_variable = cppmp::generic_predicate<__impl::member_variable_builder> { }; | |||
| } | |||
| #include "member_variable.inl" | |||
| @@ -86,7 +86,8 @@ namespace cpprtti | |||
| static constexpr decltype(auto) is_read_only_v = | |||
| cppmp::is_const_v<cppmp::remove_reference_t<object_type>> | |||
| || cppmp::is_const_v<cppmp::remove_reference_t<value_type>>; | |||
| || cppmp::is_const_v<cppmp::remove_reference_t<value_type>> | |||
| || !cppmp::is_copy_assignable_v<value_type>; | |||
| }; | |||
| /* setter_info_trait */ | |||
| @@ -1,8 +1,12 @@ | |||
| #pragma once | |||
| #include <map> | |||
| #include <string> | |||
| #include <functional> | |||
| #include <cpprtti/misc/helper.h> | |||
| #include <cpprtti/misc/variant.h> | |||
| #include <cpprtti/misc/storage.h> | |||
| namespace cpprtti | |||
| { | |||
| @@ -22,12 +26,21 @@ namespace cpprtti | |||
| * @brief represents any C++ type | |||
| */ | |||
| struct type | |||
| : public storage_container | |||
| { | |||
| public: | |||
| using converter = std::function<variant(variant)>; | |||
| using converter_map = std::map<type_id, converter>; | |||
| template<typename T_base> | |||
| friend struct type_decorator; | |||
| protected: | |||
| cpprtti::registry& _registry; //!< Type registry this type belongs to. | |||
| type_id _id; //!< Unique ID | |||
| std::string _name; //!< Name of the type. | |||
| rtti_type_t _rtti_type; //!< Type specialization | |||
| rtti_type_t _rtti_type; //!< Type specialization. | |||
| converter_map _converters; //!< Convert this type to another type. | |||
| public: | |||
| /** | |||
| @@ -68,8 +81,28 @@ namespace cpprtti | |||
| * @brief Get the RTTI type of this type object. | |||
| */ | |||
| inline rtti_type_t rtti_type() const; | |||
| /** | |||
| * @brief Get a converter that can convert this type to the passed type. | |||
| */ | |||
| template<typename T_to> | |||
| inline const converter* convert_to() const; | |||
| /** | |||
| * @brief Get a converter that can convert this type to the passed type ID. | |||
| */ | |||
| inline const converter* convert_to(type_id id) const; | |||
| /** | |||
| * @brief Get a converter that can convert the passed type to this type. | |||
| */ | |||
| template<typename T_from> | |||
| inline const converter* convert_from() const; | |||
| /** | |||
| * @brief Get a converter that can convert the passed type ID to this type. | |||
| */ | |||
| inline const converter* convert_from(type_id id) const; | |||
| }; | |||
| } | |||
| #include "type.inl" | |||
| @@ -1,6 +1,7 @@ | |||
| #pragma once | |||
| #include "type.h" | |||
| #include "../registry.h" | |||
| namespace cpprtti | |||
| { | |||
| @@ -33,4 +34,38 @@ namespace cpprtti | |||
| rtti_type_t type::rtti_type() const | |||
| { return _rtti_type; } | |||
| template<typename T_to> | |||
| const type::converter* type::convert_to() const | |||
| { | |||
| using to_type = cppmp::decay_t<T_to>; | |||
| return convert_to(get_type_id<to_type>()); | |||
| } | |||
| const type::converter* type::convert_to(type_id id) const | |||
| { | |||
| auto it = _converters.find(id); | |||
| return it == _converters.end() | |||
| ? nullptr | |||
| : &it->second; | |||
| } | |||
| template<typename T_from> | |||
| const type::converter* type::convert_from() const | |||
| { | |||
| using from_type = cppmp::decay_t<T_from>; | |||
| return convert_from(get_type_id<from_type>()); | |||
| } | |||
| const type::converter* type::convert_from(type_id id) const | |||
| { | |||
| auto* type = _registry.find(id); | |||
| if (!type) | |||
| return nullptr; | |||
| auto it = type->_converters.find(this->_id); | |||
| return it == type->_converters.end() | |||
| ? nullptr | |||
| : &it->second; | |||
| } | |||
| } | |||
| @@ -0,0 +1,32 @@ | |||
| #pragma once | |||
| #include "type.h" | |||
| namespace cpprtti | |||
| { | |||
| template<typename T_base> | |||
| struct type_decorator | |||
| : public T_base | |||
| { | |||
| public: | |||
| using base_type = T_base; | |||
| using converter = typename type::converter; | |||
| public: | |||
| using base_type::base_type; | |||
| /** | |||
| * @brief Set the converter that can convert this type to the passed type. | |||
| */ | |||
| template<typename T_to> | |||
| inline auto& convert_to(const converter& p_converter); | |||
| /** | |||
| * @brief Set the converter that can convert the passed type to this type. | |||
| */ | |||
| template<typename T_from> | |||
| inline auto& convert_from(const converter& p_converter); | |||
| }; | |||
| } | |||
| @@ -0,0 +1,39 @@ | |||
| #pragma once | |||
| #include <cppmp/core/modifier.h> | |||
| #include "type_decorator.h" | |||
| #include "../misc/helper.h" | |||
| namespace cpprtti | |||
| { | |||
| /* type_decorator */ | |||
| template<typename T_base> | |||
| template<typename T_to> | |||
| auto& type_decorator<T_base> | |||
| ::convert_to(const converter& p_converter) | |||
| { | |||
| using to_type = cppmp::decay_t<T_to>; | |||
| auto id = get_type_id<to_type>(); | |||
| this->_converters[id] = p_converter; | |||
| return *this; | |||
| } | |||
| template<typename T_base> | |||
| template<typename T_from> | |||
| auto& type_decorator<T_base> | |||
| ::convert_from(const converter& p_converter) | |||
| { | |||
| using from_type = T_from; | |||
| auto& type = this->_registry.template get<from_type>(); | |||
| type._converters[this->_id] = p_converter; | |||
| return *this; | |||
| } | |||
| } | |||
| @@ -1,38 +1,37 @@ | |||
| # Initialize ###################################################################################### | |||
| Include ( cotire OPTIONAL RESULT_VARIABLE HAS_COTIRE ) | |||
| Include ( pedantic OPTIONAL RESULT_VARIABLE HAS_PEDANTIC ) | |||
| Include ( strip_symbols OPTIONAL RESULT_VARIABLE HAS_STRIP_SYMBOLS ) | |||
| Include ( cotire OPTIONAL RESULT_VARIABLE HAS_COTIRE ) | |||
| Include ( pedantic OPTIONAL RESULT_VARIABLE HAS_PEDANTIC ) | |||
| Include ( strip_symbols OPTIONAL RESULT_VARIABLE HAS_STRIP_SYMBOLS ) | |||
| Find_Package ( cppcore ) | |||
| Find_Package ( cppmp ) | |||
| Find_Package ( cppmp ) | |||
| Find_Package ( cppcore ) | |||
| # Object Library ################################################################################## | |||
| # Interface Library ############################################################################### | |||
| Set ( CPPRTTI_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../include ) | |||
| Add_Library ( cpprtti | |||
| INTERFACE ) | |||
| Target_Include_Directories ( cpprtti | |||
| INTERFACE | |||
| $<BUILD_INTERFACE:${CPPRTTI_INCLUDE_DIR}> | |||
| $<INSTALL_INTERFACE:${CPPRTTI_INSTALL_DIR_INCLUDE}> ) | |||
| Target_Link_Libraries ( cpprtti | |||
| INTERFACE | |||
| cppcore | |||
| cppmp ) | |||
| Set ( CPPRTTI_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../include ) | |||
| Add_Library ( cpprtti INTERFACE ) | |||
| Target_Include_Directories ( cpprtti | |||
| INTERFACE | |||
| $<BUILD_INTERFACE:${CPPRTTI_INCLUDE_DIR}> | |||
| $<INSTALL_INTERFACE:${CPPRTTI_INSTALL_DIR_INCLUDE}> ) | |||
| Target_Link_Libraries ( cpprtti | |||
| INTERFACE | |||
| cppmp | |||
| cppcore ) | |||
| # Install ######################################################################################### | |||
| Set ( CPPRTTI_HAS_EXPORT False PARENT_SCOPE ) | |||
| Set ( CPPRTTI_HAS_EXPORT False PARENT_SCOPE ) | |||
| # Header | |||
| If ( CPPRTTI_INSTALL_HEADER ) | |||
| Set ( CPPRTTI_HAS_EXPORT True PARENT_SCOPE ) | |||
| Install ( FILES ${CPPRTTI_INCLUDE_DIR}/cpprtti.h | |||
| DESTINATION ${CPPRTTI_INSTALL_DIR_INCLUDE} ) | |||
| Install ( DIRECTORY ${CPPRTTI_INCLUDE_DIR}/cpprtti | |||
| DESTINATION ${CPPRTTI_INSTALL_DIR_INCLUDE} ) | |||
| Install ( TARGETS cpprtti | |||
| EXPORT cpprtti | |||
| DESTINATION ${CPPRTTI_INSTALL_DIR_INCLUDE} ) | |||
| EndIf ( ) | |||
| If ( CPPRTTI_INSTALL_HEADER ) | |||
| Set ( CPPRTTI_HAS_EXPORT True PARENT_SCOPE ) | |||
| Install ( FILES ${CPPRTTI_INCLUDE_DIR}/cpprtti.h | |||
| DESTINATION ${CPPRTTI_INSTALL_DIR_INCLUDE} ) | |||
| Install ( DIRECTORY ${CPPRTTI_INCLUDE_DIR}/cpprtti | |||
| DESTINATION ${CPPRTTI_INSTALL_DIR_INCLUDE} ) | |||
| Install ( TARGETS cpprtti | |||
| EXPORT cpprtti | |||
| DESTINATION ${CPPRTTI_INSTALL_DIR_INCLUDE} ) | |||
| EndIf ( ) | |||
| @@ -1,52 +1,59 @@ | |||
| # Initialize ###################################################################################### | |||
| Include ( cotire OPTIONAL RESULT_VARIABLE HAS_COTIRE ) | |||
| Include ( pedantic OPTIONAL RESULT_VARIABLE HAS_PEDANTIC ) | |||
| Include ( cmake_tests OPTIONAL RESULT_VARIABLE HAS_CMAKE_TESTS ) | |||
| Include ( cotire OPTIONAL RESULT_VARIABLE HAS_COTIRE ) | |||
| Include ( pedantic OPTIONAL RESULT_VARIABLE HAS_PEDANTIC ) | |||
| Include ( cmake_tests OPTIONAL RESULT_VARIABLE HAS_CMAKE_TESTS ) | |||
| Find_Package ( Sanitizers QUIET ) | |||
| # Test ############################################################################################ | |||
| Find_Package ( GTest ) | |||
| If ( NOT "${GTest_FOUND}" ) | |||
| Return ( ) | |||
| EndIf ( ) | |||
| Find_Package ( GTest ) | |||
| If ( NOT "${GTest_FOUND}" ) | |||
| Return ( ) | |||
| EndIf ( ) | |||
| File ( GLOB_RECURSE CPPRTTI_TEST_HEADER_FILES | |||
| ${CMAKE_CURRENT_SOURCE_DIR}/*.h ) | |||
| File ( GLOB_RECURSE CPPRTTI_TEST_INLINE_FILES | |||
| ${CMAKE_CURRENT_SOURCE_DIR}/*.inl ) | |||
| File ( GLOB_RECURSE CPPRTTI_TEST_SOURCE_FILES | |||
| RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} | |||
| ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp ) | |||
| File ( GLOB_RECURSE CPPRTTI_TEST_HEADER_FILES | |||
| ${CMAKE_CURRENT_SOURCE_DIR}/*.h ) | |||
| File ( GLOB_RECURSE CPPRTTI_TEST_INLINE_FILES | |||
| ${CMAKE_CURRENT_SOURCE_DIR}/*.inl ) | |||
| File ( GLOB_RECURSE CPPRTTI_TEST_SOURCE_FILES | |||
| RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} | |||
| ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp ) | |||
| ForEach ( FILE IN LISTS CPPRTTI_TEST_SOURCE_FILES ) | |||
| ForEach ( FILE IN LISTS CPPRTTI_TEST_SOURCE_FILES ) | |||
| # add test | |||
| Get_Filename_Component ( TEST_DIR ${FILE} DIRECTORY ) | |||
| Get_Filename_Component ( TEST_NAME ${FILE} NAME_WE ) | |||
| Set ( TEST_NAME "${TEST_DIR}/${TEST_NAME}" ) | |||
| String ( REPLACE "\\" "-" TEST_NAME "${TEST_NAME}" ) | |||
| String ( REPLACE "/" "-" TEST_NAME "${TEST_NAME}" ) | |||
| String ( REPLACE "_" "-" TEST_NAME "${TEST_NAME}" ) | |||
| Set ( TEST_NAME "test-${TEST_NAME}" ) | |||
| Add_Executable ( ${TEST_NAME} | |||
| EXCLUDE_FROM_ALL | |||
| ${CPPRTTI_TEST_HEADER_FILES} | |||
| ${CPPRTTI_TEST_INLINE_FILES} | |||
| ${FILE} ) | |||
| Target_Link_Libraries ( ${TEST_NAME} | |||
| PUBLIC | |||
| cpprtti | |||
| GTest::Main ) | |||
| Get_Filename_Component ( TEST_DIR ${FILE} DIRECTORY ) | |||
| Get_Filename_Component ( TEST_NAME ${FILE} NAME_WE ) | |||
| Set ( TEST_NAME "${TEST_DIR}/${TEST_NAME}" ) | |||
| String ( REPLACE "\\" "-" TEST_NAME "${TEST_NAME}" ) | |||
| String ( REPLACE "/" "-" TEST_NAME "${TEST_NAME}" ) | |||
| String ( REPLACE "_" "-" TEST_NAME "${TEST_NAME}" ) | |||
| Set ( TEST_NAME "test-${TEST_NAME}" ) | |||
| Add_Executable ( ${TEST_NAME} | |||
| EXCLUDE_FROM_ALL | |||
| ${CPPRTTI_TEST_HEADER_FILES} | |||
| ${CPPRTTI_TEST_INLINE_FILES} | |||
| ${FILE} ) | |||
| Target_Link_Libraries ( ${TEST_NAME} | |||
| PUBLIC | |||
| cpprtti | |||
| GTest::Main ) | |||
| # Sanitizers | |||
| If ( Sanitizers_FOUND ) | |||
| Add_Sanitizers ( ${TEST_NAME} ) | |||
| EndIf ( ) | |||
| # pedantic | |||
| If ( HAS_PEDANTIC ) | |||
| Pedantic_Apply_Flags_Target ( ${TEST_NAME} ALL ) | |||
| EndIf ( ) | |||
| If ( HAS_PEDANTIC ) | |||
| Pedantic_Apply_Flags_Target ( ${TEST_NAME} ALL ) | |||
| EndIf ( ) | |||
| # test | |||
| If ( HAS_CMAKE_TESTS ) | |||
| Add_CMake_Test ( NAME ${TEST_NAME} TARGET ${TEST_NAME} GROUP cpprtti ) | |||
| Else ( ) | |||
| Add_Test ( NAME ${TEST_NAME} COMMAND ${TEST_NAME} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} ) | |||
| EndIf ( ) | |||
| EndForEach ( ) | |||
| If ( HAS_CMAKE_TESTS ) | |||
| Add_CMake_Test ( NAME ${TEST_NAME} TARGET ${TEST_NAME} GROUP cpprtti ) | |||
| Else ( ) | |||
| Add_Test ( NAME ${TEST_NAME} COMMAND ${TEST_NAME} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} ) | |||
| EndIf ( ) | |||
| EndForEach ( ) | |||
| @@ -1,5 +1,6 @@ | |||
| #include <gtest/gtest.h> | |||
| #include <cpprtti/misc/variant.h> | |||
| #include <cpprtti.h> | |||
| using namespace cpprtti; | |||
| @@ -1,4 +1,5 @@ | |||
| #include <gtest/gtest.h> | |||
| #include <cpprtti.h> | |||
| using namespace cpprtti; | |||