| @@ -1,15 +1,57 @@ | |||
| # Initialize CMake ################################################################################ | |||
| CMake_Minimum_Required ( VERSION 3.5.1 FATAL_ERROR ) | |||
| Include ( CTest ) | |||
| If ( NOT CMAKE_BUILD_TYPE ) | |||
| Set ( CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build!" FORCE ) | |||
| EndIf ( NOT CMAKE_BUILD_TYPE ) | |||
| Set ( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} | |||
| "${CMAKE_CURRENT_SOURCE_DIR}/cmake/" | |||
| "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules/" ) | |||
| # Projects ######################################################################################## | |||
| Add_SubDirectory ( ${CMAKE_CURRENT_SOURCE_DIR}/src ) | |||
| Add_SubDirectory ( ${CMAKE_CURRENT_SOURCE_DIR}/test ) | |||
| 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 ) | |||
| # 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 ( ) | |||
| # Project ######################################################################################### | |||
| Include ( ${CMAKE_CURRENT_SOURCE_DIR}/cmake/cpphibernate-var.cmake ) | |||
| Include ( ${CMAKE_CURRENT_SOURCE_DIR}/cmake/cpphibernate-options.cmake ) | |||
| Project ( cpphibernate | |||
| DESCRIPTION "A simple library" | |||
| VERSION "${CPPHIBERNATE_VERSION}" ) | |||
| Include ( CTest ) | |||
| Include ( GNUInstallDirs ) | |||
| # Subdirectories | |||
| Add_SubDirectory ( ${CMAKE_CURRENT_SOURCE_DIR}/src ) | |||
| Add_SubDirectory ( ${CMAKE_CURRENT_SOURCE_DIR}/test ) | |||
| # Install | |||
| Include ( CMakePackageConfigHelpers ) | |||
| Write_Basic_Package_Version_File ( "${CMAKE_CURRENT_BINARY_DIR}/cmake/cpphibernate-config-version.cmake" | |||
| VERSION ${CPPHIBERNATE_VERSION} | |||
| COMPATIBILITY AnyNewerVersion ) | |||
| Configure_File ( "${CMAKE_CURRENT_SOURCE_DIR}/cmake/cpphibernate-config.cmake" | |||
| "${CMAKE_CURRENT_BINARY_DIR}/cmake/cpphibernate-config.cmake" | |||
| @ONLY ) | |||
| Set ( ConfigPackageLocation "${CPPHIBERNATE_INSTALL_DIR_SHARE}/cmake" ) | |||
| Install ( EXPORT | |||
| cpphibernate | |||
| NAMESPACE | |||
| cpphibernate:: | |||
| DESTINATION | |||
| ${ConfigPackageLocation} ) | |||
| Install ( FILES | |||
| "${CMAKE_CURRENT_BINARY_DIR}/cmake/cpphibernate-config.cmake" | |||
| "${CMAKE_CURRENT_BINARY_DIR}/cmake/cpphibernate-config-version.cmake" | |||
| DESTINATION | |||
| ${ConfigPackageLocation} | |||
| COMPONENT | |||
| Devel ) | |||
| @@ -1,46 +0,0 @@ | |||
| Include ( ExternalProject ) | |||
| Include ( FindPackageHandleStandardArgs ) | |||
| Set ( CPPMARIADB_PATH ${CMAKE_BINARY_DIR}/extern/cppmariadb ) | |||
| If ( NOT TARGET cppmariadb_extern ) | |||
| ExternalProject_Add ( cppmariadb_extern | |||
| PREFIX ${CPPMARIADB_PATH} | |||
| TMP_DIR ${CPPMARIADB_PATH}/tmp | |||
| STAMP_DIR ${CPPMARIADB_PATH}/stamp | |||
| SOURCE_DIR ${CPPMARIADB_PATH}/src | |||
| BINARY_DIR ${CPPMARIADB_PATH}/build | |||
| INSTALL_DIR ${CPPMARIADB_PATH}/install | |||
| GIT_REPOSITORY "https://git.bergmann89.de/cpp/cppmariadb.git" | |||
| GIT_TAG "master" | |||
| TEST_COMMAND make test | |||
| CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=<INSTALL_DIR> | |||
| -DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS} | |||
| -DCMAKE_C_FLAGS=${CMAKE_C_FLAGS} | |||
| -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} | |||
| -DCMAKE_MODULE_PATH=${CMAKE_MODULE_PATH}) | |||
| EndIf ( ) | |||
| Set ( CPPMARIADB_LIBRARY ${CPPMARIADB_PATH}/install/lib/libcppmariadb.so ) | |||
| Set ( CPPMARIADB_INCLUDE_DIR ${CPPMARIADB_PATH}/install/include ) | |||
| Set ( CPPMARIADB_LIBRARIES ${CPPMARIADB_LIBRARY} ) | |||
| Set ( CPPMARIADB_INCLUDE_DIRS ${CPPMARIADB_INCLUDE_DIR} ) | |||
| File ( MAKE_DIRECTORY ${CPPMARIADB_INCLUDE_DIR} ) | |||
| Find_Package_Handle_Standard_Args ( cppmariadb DEFAULT_MSG | |||
| CPPMARIADB_LIBRARY | |||
| CPPMARIADB_INCLUDE_DIR ) | |||
| If ( NOT TARGET cppmariadb ) | |||
| Add_Library ( cppmariadb SHARED IMPORTED ) | |||
| Add_Dependencies ( cppmariadb cppmariadb_extern ) | |||
| Set_Property ( TARGET cppmariadb | |||
| PROPERTY IMPORTED_LOCATION ${CPPMARIADB_LIBRARY} ) | |||
| Set_Property ( TARGET cppmariadb | |||
| PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${CPPMARIADB_INCLUDE_DIRS} ) | |||
| Install ( FILES ${CPPMARIADB_LIBRARY} DESTINATION lib ) | |||
| If ( CPPHIBERNATE_INSTALL_DEV_FILES ) | |||
| Install ( DIRECTORY ${CPPMARIADB_INCLUDE_DIR}/ DESTINATION include ) | |||
| EndIf ( ) | |||
| EndIf ( ) | |||
| @@ -1,46 +0,0 @@ | |||
| Include ( ExternalProject ) | |||
| Include ( FindPackageHandleStandardArgs ) | |||
| Set ( CPPUTILS_PATH ${CMAKE_BINARY_DIR}/extern/cpputils ) | |||
| If ( NOT TARGET cpputils_extern ) | |||
| ExternalProject_Add ( cpputils_extern | |||
| PREFIX ${CPPUTILS_PATH} | |||
| TMP_DIR ${CPPUTILS_PATH}/tmp | |||
| STAMP_DIR ${CPPUTILS_PATH}/stamp | |||
| SOURCE_DIR ${CPPUTILS_PATH}/src | |||
| BINARY_DIR ${CPPUTILS_PATH}/build | |||
| INSTALL_DIR ${CPPUTILS_PATH}/install | |||
| GIT_REPOSITORY "https://git.bergmann89.de/cpp/cpputils.git" | |||
| GIT_TAG "master" | |||
| TEST_COMMAND make test | |||
| CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=<INSTALL_DIR> | |||
| -DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS} | |||
| -DCMAKE_C_FLAGS=${CMAKE_C_FLAGS} | |||
| -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} | |||
| -DCMAKE_MODULE_PATH=${CMAKE_MODULE_PATH}) | |||
| EndIf ( ) | |||
| Set ( CPPUTILS_LIBRARY ${CPPUTILS_PATH}/install/lib/libcpputils.so ) | |||
| Set ( CPPUTILS_INCLUDE_DIR ${CPPUTILS_PATH}/install/include ) | |||
| Set ( CPPUTILS_LIBRARIES ${CPPUTILS_LIBRARY} ) | |||
| Set ( CPPUTILS_INCLUDE_DIRS ${CPPUTILS_INCLUDE_DIR} ) | |||
| File ( MAKE_DIRECTORY ${CPPUTILS_INCLUDE_DIR} ) | |||
| Find_Package_Handle_Standard_Args ( cpputils DEFAULT_MSG | |||
| CPPUTILS_LIBRARY | |||
| CPPUTILS_INCLUDE_DIR ) | |||
| If ( NOT TARGET cpputils ) | |||
| Add_Library ( cpputils SHARED IMPORTED ) | |||
| Add_Dependencies ( cpputils cpputils_extern ) | |||
| Set_Property ( TARGET cpputils | |||
| PROPERTY IMPORTED_LOCATION ${CPPUTILS_LIBRARY} ) | |||
| Set_Property ( TARGET cpputils | |||
| PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${CPPUTILS_INCLUDE_DIRS} ) | |||
| Install ( FILES ${CPPUTILS_LIBRARY} DESTINATION lib ) | |||
| If ( CPPHIBERNATE_INSTALL_DEV_FILES ) | |||
| Install ( DIRECTORY ${CPPUTILS_INCLUDE_DIR}/ DESTINATION include ) | |||
| EndIf ( ) | |||
| EndIf ( ) | |||
| @@ -1,34 +0,0 @@ | |||
| Find_Library ( MARIADB_LIBRARY | |||
| NAMES mariadb mysql | |||
| PATH_SUFFIXES mariadb ) | |||
| Find_File ( MARIADB_INCLUDE_DIR | |||
| NAMES mysql.h | |||
| PATH_SUFFIXES mariadb ) | |||
| Get_Filename_Component ( MARIADB_INCLUDE_DIR | |||
| ${MARIADB_INCLUDE_DIR} | |||
| DIRECTORY ) | |||
| Include ( FindPackageHandleStandardArgs ) | |||
| Find_Package_Handle_Standard_Args ( mariadb DEFAULT_MSG | |||
| MARIADB_LIBRARY | |||
| MARIADB_INCLUDE_DIR ) | |||
| Mark_As_Advanced ( MARIADB_LIBRARY | |||
| MARIADB_LIBRARIES ) | |||
| If ( MARIADB_FOUND ) | |||
| Set ( MARIADB_LIBRARIES ${MARIADB_LIBRARY} ) | |||
| Set ( MARIADB_INCLUDE_DIRS ${MARIADB_INCLUDE_DIR} ) | |||
| If ( NOT TARGET mariadb ) | |||
| Add_Library ( mariadb UNKNOWN IMPORTED ) | |||
| Set_Property ( TARGET mariadb | |||
| PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${MARIADB_INCLUDE_DIRS}" ) | |||
| Set_Property ( TARGET mariadb | |||
| APPEND | |||
| PROPERTY IMPORTED_LOCATION "${MARIADB_LIBRARY}") | |||
| EndIf ( ) | |||
| EndIf ( ) | |||
| @@ -0,0 +1,10 @@ | |||
| # cpphibernate-config.cmake - package configuration file | |||
| Message ( WARNING "Please configure the dependencies of this package!" ) | |||
| # Include ( CMakeFindDependencyMacro ) | |||
| # Find_Dependency ( <dependency> ) | |||
| Include ( FindPackageHandleStandardArgs ) | |||
| Set ( ${CMAKE_FIND_PACKAGE_NAME}_CONFIG ${CMAKE_CURRENT_LIST_FILE} ) | |||
| Find_Package_Handle_Standard_Args ( cpphibernate CONFIG_MODE ) | |||
| Include ( "${CMAKE_CURRENT_LIST_DIR}/cpphibernate.cmake") | |||
| @@ -0,0 +1,15 @@ | |||
| Option ( CPPHIBERNATE_INSTALL_HEADER | |||
| "Install headers of cpphibernate." | |||
| ON ) | |||
| Option ( CPPHIBERNATE_INSTALL_STATIC | |||
| "Install static library of cpphibernate." | |||
| ON ) | |||
| Option ( CPPHIBERNATE_INSTALL_SHARED | |||
| "Install shared library of cpphibernate." | |||
| ON ) | |||
| Option ( CPPHIBERNATE_INSTALL_DEBUG | |||
| "Install the stripped debug informations of cpphibernate." | |||
| OFF ) | |||
| Option ( CPPHIBERNATE_NO_STRIP | |||
| "Do not strip debug symbols from binary." | |||
| OFF ) | |||
| @@ -0,0 +1,31 @@ | |||
| # Version | |||
| Set ( CPPHIBERNATE_VERSION_MAJOR 1 ) | |||
| Set ( CPPHIBERNATE_VERSION_MINOR 0 ) | |||
| Set ( CPPHIBERNATE_VERSION_PATCH 0 ) | |||
| Set ( CPPHIBERNATE_VERSION_BUILD 0 ) | |||
| Set ( CPPHIBERNATE_VERSION_SHORT "${CPPHIBERNATE_VERSION_MAJOR}.${CPPHIBERNATE_VERSION_MINOR}" ) | |||
| Set ( CPPHIBERNATE_VERSION "${CPPHIBERNATE_VERSION_SHORT}.${CPPHIBERNATE_VERSION_PATCH}.${CPPHIBERNATE_VERSION_BUILD}" ) | |||
| Set ( CPPHIBERNATE_NAME "cpphibernate-${CPPHIBERNATE_VERSION_SHORT}" ) | |||
| Set ( CPPHIBERNATE_OUTPUTNAME "cpphibernate" ) | |||
| # Install directories | |||
| Set ( CPPHIBERNATE_INSTALL_DIR_INCLUDE "include/${CPPHIBERNATE_NAME}" ) | |||
| Set ( CPPHIBERNATE_INSTALL_DIR_LIB "lib" ) | |||
| Set ( CPPHIBERNATE_INSTALL_DIR_SHARE "share/${CPPHIBERNATE_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 ) | |||
| # Git Version | |||
| Include ( git_helper OPTIONAL RESULT_VARIABLE HAS_GIT_HELPER ) | |||
| If ( HAS_GIT_HELPER ) | |||
| GitGetVersion ( ${CMAKE_CURRENT_LIST_DIR}/.. | |||
| CPPHIBERNATE_VERSION_MAJOR | |||
| CPPHIBERNATE_VERSION_MINOR | |||
| CPPHIBERNATE_VERSION_PATCH | |||
| CPPHIBERNATE_VERSION_BUILD | |||
| CPPHIBERNATE_VERSION_HASH ) | |||
| EndIf ( ) | |||
| @@ -1 +1 @@ | |||
| Subproject commit b125a1a176ae0aada1cd2ec90919061d202dcea9 | |||
| Subproject commit 1a32531aef2deeebd5637b1873bc4e976628801c | |||
| @@ -1,9 +0,0 @@ | |||
| Option ( CPPHIBERNATE_BUILD_SHARED | |||
| "Build cpphibernate shared library" | |||
| ON ) | |||
| Option ( CPPHIBERNATE_INSTALL_DEV_FILES | |||
| "Install development files of cpphibernate" | |||
| ON ) | |||
| Option ( CPPHIBERNATE_DEBUG | |||
| "Enable debug output" | |||
| OFF ) | |||
| @@ -1 +0,0 @@ | |||
| #cmakedefine CPPHIBERNATE_DEBUG | |||
| @@ -1,8 +1,5 @@ | |||
| #pragma once | |||
| #include <cpphibernate/config.h> | |||
| #include <cpphibernate/context.h> | |||
| #include <cpphibernate/misc.h> | |||
| #include <cpphibernate/modifier.h> | |||
| #include <cpphibernate/schema.h> | |||
| #include <cpphibernate/types.h> | |||
| #include "cpphibernate/misc.h" | |||
| #include "cpphibernate/schema.h" | |||
| #include "cpphibernate/types.h" | |||
| @@ -1,73 +1,12 @@ | |||
| #pragma once | |||
| #include <cppmp.h> | |||
| #include <boost/hana.hpp> | |||
| #include <cpputils/mp/core.h> | |||
| #include <cpphibernate/options.h> | |||
| #ifdef CPPHIBERNATE_DEBUG | |||
| # include <cpputils/logging/global.h> | |||
| # define cpphibernate_debug_log(...) log_global_message(debug) << __VA_ARGS__ | |||
| #else | |||
| # define cpphibernate_debug_log(...) do { } while(0) | |||
| #endif | |||
| #define cpphibernate_equality_comparable() \ | |||
| template<typename T_other> \ | |||
| constexpr decltype(auto) operator==(T_other&&) const \ | |||
| { \ | |||
| return ::boost::hana::type<::utl::mp::decay_t<decltype(*this)>> { } == \ | |||
| ::boost::hana::type<::utl::mp::decay_t<T_other>> { }; \ | |||
| } \ | |||
| \ | |||
| template<typename T_other> \ | |||
| constexpr decltype(auto) operator!=(T_other&&) const \ | |||
| { \ | |||
| return ::boost::hana::type<::utl::mp::decay_t<decltype(*this)>> { } != \ | |||
| ::boost::hana::type<::utl::mp::decay_t<T_other>> { }; \ | |||
| } | |||
| #define cpphibernate_constructable(name, value) \ | |||
| name() = value | |||
| #define cpphibernate_copyable(name, value) \ | |||
| name(const name&) = value; \ | |||
| name& operator=(const name&) = value | |||
| #define cpphibernate_moveable(name, value) \ | |||
| name(name&&) = value; \ | |||
| name& operator=(name&&) = value | |||
| #define cpphibernate_define_namespace_beg(parent, name) \ | |||
| parent { \ | |||
| namespace name | |||
| #define cpphibernate_define_namespace_end(parent) \ | |||
| } \ | |||
| parent | |||
| #define beg_namespace_cpphibernate namespace cpphibernate | |||
| #define end_namespace_cpphibernate | |||
| #define beg_namespace_cpphibernate_schema cpphibernate_define_namespace_beg(beg_namespace_cpphibernate, schema) | |||
| #define end_namespace_cpphibernate_schema cpphibernate_define_namespace_end(end_namespace_cpphibernate) | |||
| #define beg_namespace_cpphibernate_misc cpphibernate_define_namespace_beg(beg_namespace_cpphibernate, misc) | |||
| #define end_namespace_cpphibernate_misc cpphibernate_define_namespace_end(end_namespace_cpphibernate) | |||
| #define beg_namespace_cpphibernate_modifier cpphibernate_define_namespace_beg(beg_namespace_cpphibernate, modifier) | |||
| #define end_namespace_cpphibernate_modifier cpphibernate_define_namespace_end(end_namespace_cpphibernate) | |||
| #define beg_namespace_cpphibernate_driver cpphibernate_define_namespace_beg(beg_namespace_cpphibernate, driver) | |||
| #define end_namespace_cpphibernate_driver cpphibernate_define_namespace_end(end_namespace_cpphibernate) | |||
| #define beg_namespace_cpphibernate_driver_mariadb cpphibernate_define_namespace_beg(beg_namespace_cpphibernate_driver, mariadb_impl) | |||
| #define end_namespace_cpphibernate_driver_mariadb cpphibernate_define_namespace_end(end_namespace_cpphibernate_driver) | |||
| beg_namespace_cpphibernate | |||
| namespace cpphibernate | |||
| { | |||
| namespace mp = ::utl::mp; | |||
| namespace mp = ::cppmp; | |||
| namespace hana = ::boost::hana; | |||
| } | |||
| end_namespace_cpphibernate | |||
| @@ -1,123 +0,0 @@ | |||
| #pragma once | |||
| #include <memory> | |||
| #include <cpphibernate/misc.h> | |||
| #include <cpphibernate/config.h> | |||
| #include <cpphibernate/schema/table.h> | |||
| #include <cpphibernate/schema/tables.h> | |||
| #include <cpphibernate/modifier/where.h> | |||
| #include <cpphibernate/modifier/modifiers.h> | |||
| beg_namespace_cpphibernate | |||
| { | |||
| namespace __impl | |||
| { | |||
| template<typename T_driver, typename T_schema> | |||
| struct context_t | |||
| : public T_driver | |||
| { | |||
| public: | |||
| using base_type = T_driver; | |||
| using driver_type = T_driver; | |||
| using schema_type = T_schema; | |||
| private: | |||
| const schema_type& _schema; | |||
| public: | |||
| template<typename... T_args> | |||
| constexpr context_t(const schema_type& p_schema, T_args&&... args) | |||
| : base_type (p_schema, std::forward<T_args>(args)...) | |||
| , _schema (p_schema) | |||
| { } | |||
| cpphibernate_copyable(context_t, delete); | |||
| cpphibernate_moveable(context_t, default); | |||
| /* init */ | |||
| inline void init(bool recreate) | |||
| { this->init_impl(recreate); } | |||
| /* create */ | |||
| template<typename T_dataset> | |||
| constexpr void create(T_dataset& dataset) | |||
| { this->create_impl(dataset); } | |||
| /* read */ | |||
| template<typename T_dataset, typename... T_modifiers> | |||
| constexpr auto read(T_dataset& dataset, T_modifiers&&... modifiers) | |||
| -> mp::enable_if< | |||
| modifier::all_are_modifiers<mp::decay_t<T_modifiers>...>> | |||
| { | |||
| using namespace modifier; | |||
| using real_dataset_type = misc::real_dataset_t<mp::decay_t<T_dataset>>; | |||
| schema::tables::find(_schema.tables, hana::type_c<real_dataset_type>); | |||
| this->read_impl(dataset, modifier::make_list(std::forward<T_modifiers>(modifiers)...)); | |||
| } | |||
| template<typename T_dataset> | |||
| constexpr auto read(T_dataset& dataset) | |||
| -> mp::enable_if_c< | |||
| !misc::is_container<mp::decay_t<T_dataset>>::value | |||
| && !misc::is_nullable<mp::decay_t<T_dataset>>::value> | |||
| { | |||
| using namespace modifier; | |||
| using real_dataset_type = misc::real_dataset_t<mp::decay_t<T_dataset>>; | |||
| auto& table = schema::tables::find(_schema.tables, hana::type_c<real_dataset_type>); | |||
| auto& primary_key = schema::table::get_primary_key_field(table); | |||
| this->read_impl(dataset, modifier::make_list(where(equal(primary_key, primary_key.getter(dataset))))); | |||
| } | |||
| template<typename T_dataset> | |||
| constexpr auto read(T_dataset& dataset) | |||
| -> mp::enable_if_c< | |||
| misc::is_container<mp::decay_t<T_dataset>>::value | |||
| || misc::is_nullable<mp::decay_t<T_dataset>>::value> | |||
| { | |||
| using namespace modifier; | |||
| using real_dataset_type = misc::real_dataset_t<mp::decay_t<T_dataset>>; | |||
| schema::tables::find(_schema.tables, hana::type_c<real_dataset_type>); | |||
| this->read_impl(dataset, modifier::make_list()); | |||
| } | |||
| /* update */ | |||
| template<typename T_dataset> | |||
| constexpr void update(T_dataset& dataset) | |||
| { this->update_impl(dataset); } | |||
| /* destroy */ | |||
| template<typename T_dataset> | |||
| constexpr void destroy(T_dataset& dataset) | |||
| { this->destroy_impl(dataset); } | |||
| }; | |||
| } | |||
| /* make */ | |||
| template<typename T_driver, typename T_schema, typename... T_args> | |||
| constexpr decltype(auto) make_context(T_schema&& schema, T_args&&... args) | |||
| { | |||
| using context_type = __impl::context_t<T_driver, T_schema>; | |||
| return context_type(std::forward<T_schema>(schema), std::forward<T_args>(args)...); | |||
| } | |||
| template<typename T_driver, typename T_schema, typename... T_args> | |||
| constexpr decltype(auto) make_context_ptr(T_schema&& schema, T_args&&... args) | |||
| { | |||
| using context_type = __impl::context_t<T_driver, T_schema>; | |||
| using pointer_type = std::unique_ptr<context_type>; | |||
| return pointer_type(new context_type(std::forward<T_schema>(schema), std::forward<T_args>(args)...)); | |||
| } | |||
| } | |||
| end_namespace_cpphibernate | |||
| @@ -1,8 +1,6 @@ | |||
| #pragma once | |||
| #include <cpphibernate/misc/container_helper.h> | |||
| #include <cpphibernate/misc/general.h> | |||
| #include <cpphibernate/misc/meta.h> | |||
| #include <cpphibernate/misc/nullable_helper.h> | |||
| #include <cpphibernate/misc/print.h> | |||
| #include <cpphibernate/misc/wrap.h> | |||
| #include "misc/equality_compare.h" | |||
| #include "misc/print_container.h" | |||
| #include "misc/printing.h" | |||
| #include "misc/type_helper.h" | |||
| @@ -1,52 +0,0 @@ | |||
| #pragma once | |||
| #include <set> | |||
| #include <list> | |||
| #include <vector> | |||
| #include <cpphibernate/config.h> | |||
| beg_namespace_cpphibernate_misc | |||
| { | |||
| /* container_helper */ | |||
| template<typename T_container, typename = void> | |||
| struct container_helper; | |||
| template<typename T_value, typename... T_args> | |||
| struct container_helper<std::vector<T_value, T_args...>, void> | |||
| { | |||
| using container_type = std::vector<T_value, T_args...>; | |||
| using value_type = T_value; | |||
| template<typename... T_xargs> | |||
| static inline value_type& emplace(container_type& container, T_xargs&&... args) | |||
| { | |||
| container.emplace_back(std::forward<T_xargs>(args)...); | |||
| return container.back(); | |||
| } | |||
| static inline void clear(container_type& container) | |||
| { container.clear(); } | |||
| }; | |||
| template<typename T_value, typename... T_args> | |||
| struct container_helper<std::list<T_value, T_args...>, void> | |||
| { | |||
| using container_type = std::list<T_value, T_args...>; | |||
| using value_type = T_value; | |||
| template<typename... T_xargs> | |||
| static inline value_type& emplace(container_type& container, T_xargs&&... args) | |||
| { | |||
| container.emplace_back(std::forward<T_xargs>(args)...); | |||
| return container.back(); | |||
| } | |||
| static inline void clear(container_type& container) | |||
| { container.clear(); } | |||
| }; | |||
| } | |||
| end_namespace_cpphibernate_misc | |||
| @@ -0,0 +1,30 @@ | |||
| #pragma once | |||
| #include <cpphibernate/config.h> | |||
| namespace cpphibernate | |||
| { | |||
| /** | |||
| * @brief Tag all objects that are equality comparable to each other. | |||
| * | |||
| * @tparam T_group Type used for groupig different types. | |||
| */ | |||
| template<typename T_group> | |||
| struct tag_equality_comparable; | |||
| /** | |||
| * @brief Equality compare for all objects that has the quality compare tag | |||
| */ | |||
| template<typename T_lhs, typename T_rhs> | |||
| constexpr decltype(auto) operator == (T_lhs&& lhs, T_rhs&& rhs); | |||
| /** | |||
| * @brief Equality compare for all objects that has the quality compare tag | |||
| */ | |||
| template<typename T_lhs, typename T_rhs> | |||
| constexpr decltype(auto) operator != (T_lhs&& lhs, T_rhs&& rhs); | |||
| } | |||
| #include "equality_compare.inl" | |||
| @@ -0,0 +1,61 @@ | |||
| #pragma once | |||
| #include "equality_compare.h" | |||
| namespace cpphibernate | |||
| { | |||
| namespace __impl | |||
| { | |||
| template<typename T_lhs, typename T_rhs, typename = void> | |||
| struct equality_compare_impl | |||
| { | |||
| static constexpr decltype(auto) equal(T_lhs&&, T_rhs&&) | |||
| { static_assert(sizeof(T_lhs) == -1, "Unable to equality compare these two types."); } | |||
| static constexpr decltype(auto) not_equal(T_lhs&&, T_rhs&&) | |||
| { static_assert(sizeof(T_lhs) == -1, "Unable to equality compare these two types."); } | |||
| }; | |||
| template<typename T_lhs, typename T_rhs> | |||
| struct equality_compare_impl< | |||
| T_lhs, | |||
| T_rhs, | |||
| mp::enable_if_t< | |||
| mp::is_valid_v<typename T_lhs::equality_compare_group_type> | |||
| && mp::is_valid_v<typename T_rhs::equality_compare_group_type> | |||
| && mp::is_same_v< | |||
| typename T_lhs::equality_compare_group_type, | |||
| typename T_rhs::equality_compare_group_type>>> | |||
| { | |||
| static constexpr decltype(auto) equal(T_lhs&&, T_rhs&&) | |||
| { return hana::type_c<mp::decay_t<T_lhs>> == hana::type_c<mp::decay_t<T_rhs>>; } | |||
| static constexpr decltype(auto) not_equal(T_lhs&&, T_rhs&&) | |||
| { return hana::type_c<mp::decay_t<T_lhs>> != hana::type_c<mp::decay_t<T_rhs>>; } | |||
| }; | |||
| }; | |||
| template<typename T_group> | |||
| struct tag_equality_comparable | |||
| { | |||
| using equality_compare_group_type = T_group; | |||
| }; | |||
| template<typename T_lhs, typename T_rhs> | |||
| constexpr decltype(auto) operator == (T_lhs&& lhs, T_rhs&& rhs) | |||
| { | |||
| using equality_compare_type = __impl::equality_compare_impl<T_lhs, T_rhs>; | |||
| return equality_compare_type::equal(std::forward<T_lhs>(lhs), std::forward<T_rhs>(rhs)); | |||
| } | |||
| template<typename T_lhs, typename T_rhs> | |||
| constexpr decltype(auto) operator != (T_lhs&& lhs, T_rhs&& rhs) | |||
| { | |||
| using equality_compare_type = __impl::equality_compare_impl<T_lhs, T_rhs>; | |||
| return equality_compare_type::not_equal(std::forward<T_lhs>(lhs), std::forward<T_rhs>(rhs)); | |||
| } | |||
| } | |||
| @@ -1,32 +0,0 @@ | |||
| #pragma once | |||
| #include <cpphibernate/config.h> | |||
| #include <cpputils/misc/type_helper.h> | |||
| beg_namespace_cpphibernate_misc | |||
| { | |||
| /* make_generic_predicate */ | |||
| template<template<typename...> class T_builder> | |||
| struct make_generic_predicate | |||
| { | |||
| template<typename... T_args> | |||
| constexpr decltype(auto) operator()(T_args&&... args) const | |||
| { return T_builder<mp::list<T_args...>>::apply(std::forward<T_args>(args)...); } | |||
| }; | |||
| /* get_dataset_id */ | |||
| namespace __impl | |||
| { | |||
| struct counter_type_id | |||
| { }; | |||
| } | |||
| template<typename T_type> | |||
| constexpr decltype(auto) get_type_id(T_type&&) | |||
| { return utl::get_unique_id<__impl::counter_type_id, mp::decay_t<T_type>>(); } | |||
| } | |||
| end_namespace_cpphibernate_misc | |||
| @@ -1,152 +0,0 @@ | |||
| #pragma once | |||
| #include <list> | |||
| #include <vector> | |||
| #include <memory> | |||
| #include <cpphibernate/config.h> | |||
| #include <cpputils/misc/exception.h> | |||
| #include <cpputils/container/nullable.h> | |||
| beg_namespace_cpphibernate_misc | |||
| { | |||
| namespace __impl | |||
| { | |||
| /* is_container_impl */ | |||
| template<typename T> | |||
| struct is_container_impl | |||
| : public mp::c_false_t | |||
| { }; | |||
| template<typename T, typename... T_args> | |||
| struct is_container_impl<std::list<T, T_args...>> | |||
| : public mp::c_true_t | |||
| { }; | |||
| template<typename T, typename... T_args> | |||
| struct is_container_impl<std::vector<T, T_args...>> | |||
| : public mp::c_true_t | |||
| { }; | |||
| /* is_nullable_impl */ | |||
| template<typename T> | |||
| struct is_nullable_impl | |||
| : public mp::c_false_t | |||
| { }; | |||
| template<typename T> | |||
| struct is_nullable_impl<utl::nullable<T>> | |||
| : public mp::c_true_t | |||
| { }; | |||
| template<typename T> | |||
| struct is_nullable_impl<std::unique_ptr<T>> | |||
| : public mp::c_true_t | |||
| { }; | |||
| template<typename T> | |||
| struct is_nullable_impl<std::shared_ptr<T>> | |||
| : public mp::c_true_t | |||
| { }; | |||
| /* is_pointer_impl */ | |||
| template<typename T> | |||
| struct is_pointer_impl | |||
| : public mp::c_false_t | |||
| { }; | |||
| template<typename T> | |||
| struct is_pointer_impl<std::unique_ptr<T>> | |||
| : public mp::c_true_t | |||
| { }; | |||
| template<typename T> | |||
| struct is_pointer_impl<std::shared_ptr<T>> | |||
| : public mp::c_true_t | |||
| { }; | |||
| /* is_ordered_impl */ | |||
| template<typename T> | |||
| struct is_ordered_impl | |||
| : public mp::c_false_t | |||
| { }; | |||
| template<typename T, typename... T_args> | |||
| struct is_ordered_impl<std::list<T, T_args...>> | |||
| : public mp::c_true_t | |||
| { }; | |||
| template<typename T, typename... T_args> | |||
| struct is_ordered_impl<std::vector<T, T_args...>> | |||
| : public mp::c_true_t | |||
| { }; | |||
| /* real_dataset_impl */ | |||
| template<typename T, typename = void> | |||
| struct real_dataset_impl | |||
| { using type = T; }; | |||
| template<typename T> | |||
| struct real_dataset_impl<utl::nullable<T>, void> | |||
| { using type = typename real_dataset_impl<T>::type; }; | |||
| template<typename T, typename... T_args> | |||
| struct real_dataset_impl<std::unique_ptr<T, T_args...>, void> | |||
| { using type = typename real_dataset_impl<T>::type; }; | |||
| template<typename T> | |||
| struct real_dataset_impl<std::shared_ptr<T>, void> | |||
| { using type = typename real_dataset_impl<T>::type; }; | |||
| template<typename T, typename... T_args> | |||
| struct real_dataset_impl<std::list<T, T_args...>, void> | |||
| { using type = typename real_dataset_impl<T>::type; }; | |||
| template<typename T, typename... T_args> | |||
| struct real_dataset_impl<std::vector<T, T_args...>, void> | |||
| { using type = typename real_dataset_impl<T>::type; }; | |||
| } | |||
| /* meta */ | |||
| template<typename T> | |||
| struct is_container | |||
| : public __impl::is_container_impl<T> | |||
| { }; | |||
| template<typename T> | |||
| struct is_nullable | |||
| : public __impl::is_nullable_impl<T> | |||
| { }; | |||
| template<typename T> | |||
| struct is_ordered | |||
| : public __impl::is_ordered_impl<T> | |||
| { }; | |||
| template<typename T> | |||
| struct is_pointer | |||
| : public __impl::is_pointer_impl<T> | |||
| { }; | |||
| template<typename T> | |||
| using real_dataset_t = typename __impl::real_dataset_impl<T>::type; | |||
| /* hibernate_exception */ | |||
| struct hibernate_exception | |||
| : public utl::exception | |||
| { | |||
| using utl::exception::exception; | |||
| }; | |||
| } | |||
| end_namespace_cpphibernate_misc | |||
| @@ -1,120 +0,0 @@ | |||
| #pragma once | |||
| #include <memory> | |||
| #include <cpphibernate/config.h> | |||
| #include <cpphibernate/misc/meta.h> | |||
| #include <cpputils/container/nullable.h> | |||
| beg_namespace_cpphibernate_misc | |||
| { | |||
| /* nullable_helper */ | |||
| template<typename T_nullable, typename = void> | |||
| struct nullable_helper | |||
| { | |||
| using nullable_type = T_nullable; | |||
| using value_type = real_dataset_t<nullable_type>; | |||
| static value_type* get (const nullable_type&) = delete; | |||
| static value_type& set (nullable_type&, const value_type&) = delete; | |||
| static void clear (nullable_type&) = delete; | |||
| }; | |||
| /* nullable_helper - utl::nullable */ | |||
| template<typename T_value> | |||
| struct nullable_helper<utl::nullable<T_value>, void> | |||
| { | |||
| using nullable_type = utl::nullable<T_value>; | |||
| using value_type = T_value; | |||
| static inline value_type* get(nullable_type& x) | |||
| { return x.has_value() ? &x.value() : nullptr; } | |||
| static inline const value_type* get(const nullable_type& x) | |||
| { return x.has_value() ? &x.value() : nullptr; } | |||
| static inline value_type& set(nullable_type& x, const value_type* value) | |||
| { return *(x = *value); } | |||
| static inline value_type& set(nullable_type& x, const value_type& value) | |||
| { return *(x = value); } | |||
| static inline value_type& set(nullable_type& x, value_type&& value) | |||
| { return *(x = std::move(value)); } | |||
| static void clear(nullable_type& x) | |||
| { x.reset(); } | |||
| }; | |||
| /* nullable_helper - std::unique_ptr */ | |||
| template<typename T_value> | |||
| struct nullable_helper<std::unique_ptr<T_value>, void> | |||
| { | |||
| using nullable_type = std::unique_ptr<T_value>; | |||
| using value_type = T_value; | |||
| static inline value_type* get(const nullable_type& x) | |||
| { return x.get(); } | |||
| static inline value_type& set(nullable_type& x, value_type* value) | |||
| { | |||
| x.reset(value); | |||
| return *x; | |||
| } | |||
| static inline value_type& set(nullable_type& x, const value_type& value) | |||
| { | |||
| x.reset(new value_type(value)); | |||
| return *x; | |||
| } | |||
| static inline value_type& set(nullable_type& x, value_type&& value) | |||
| { | |||
| x.reset(new value_type(std::move(value))); | |||
| return *x; | |||
| } | |||
| static void clear(nullable_type& x) | |||
| { return x.reset(); } | |||
| }; | |||
| /* nullable_helper - std::shared_ptr */ | |||
| template<typename T_value> | |||
| struct nullable_helper<std::shared_ptr<T_value>, void> | |||
| { | |||
| using nullable_type = std::shared_ptr<T_value>; | |||
| using value_type = T_value; | |||
| static inline value_type* get(const nullable_type& x) | |||
| { return x.get(); } | |||
| static inline value_type& set(nullable_type& x, value_type* value) | |||
| { | |||
| x.reset(value); | |||
| return *x; | |||
| } | |||
| static inline value_type& set(nullable_type& x, const value_type& value) | |||
| { | |||
| x.reset(new value_type(value)); | |||
| return *x; | |||
| } | |||
| static inline value_type& set(nullable_type& x, value_type&& value) | |||
| { | |||
| x.reset(new value_type(std::move(value))); | |||
| return *x; | |||
| } | |||
| static void clear(nullable_type& x) | |||
| { return x.reset(); } | |||
| }; | |||
| } | |||
| end_namespace_cpphibernate_misc | |||
| @@ -1,112 +0,0 @@ | |||
| #pragma once | |||
| #include <list> | |||
| #include <vector> | |||
| #include <memory> | |||
| #include <iostream> | |||
| #include <cpphibernate/config.h> | |||
| #include <cpputils/misc/indent.h> | |||
| namespace std | |||
| { | |||
| template<typename T_char, typename T_traits, typename X> | |||
| inline auto operator <<(basic_ostream<T_char, T_traits>& os, X&& x) | |||
| -> ::utl::mp::enable_if< | |||
| utl::mp::is_valid<decltype(std::forward<X>(x).print(os))>, | |||
| basic_ostream<T_char, T_traits>&> | |||
| { | |||
| std::forward<X>(x).print(os); | |||
| return os; | |||
| } | |||
| } | |||
| beg_namespace_cpphibernate_misc | |||
| { | |||
| template<typename T_container, typename T_func> | |||
| struct container_printer | |||
| { | |||
| T_container container; | |||
| bool do_indent; | |||
| T_func func; | |||
| inline void print(std::ostream& os) const | |||
| { | |||
| using namespace ::utl; | |||
| auto beg = std::begin(container); | |||
| auto end = std::end (container); | |||
| if (beg != end) | |||
| { | |||
| if (do_indent) | |||
| { | |||
| os << indent << "[" | |||
| << incindent; | |||
| } | |||
| else | |||
| { | |||
| os << "["; | |||
| } | |||
| size_t index = 0; | |||
| for (auto it = beg; it != end; ++it) | |||
| { | |||
| if (index++) | |||
| os << ","; | |||
| if (!do_indent) | |||
| os << " "; | |||
| func(os, *it); | |||
| } | |||
| if (do_indent) | |||
| { | |||
| os << decindent | |||
| << indent << "]"; | |||
| } | |||
| else | |||
| { | |||
| os << " ]"; | |||
| } | |||
| } | |||
| else | |||
| { | |||
| os << "[ ]"; | |||
| } | |||
| } | |||
| }; | |||
| struct print_container_builder | |||
| { | |||
| template<typename T_container, typename T_func> | |||
| constexpr decltype(auto) operator()(T_container&& container, bool do_indent, T_func&& func) const | |||
| { | |||
| return container_printer<T_container, T_func> | |||
| { | |||
| std::forward<T_container>(container), | |||
| do_indent, | |||
| std::forward<T_func>(func) | |||
| }; | |||
| } | |||
| template<typename T_container> | |||
| constexpr decltype(auto) operator()(T_container&& container, bool do_indent) const | |||
| { | |||
| return this->operator()( | |||
| std::forward<T_container>(container), | |||
| do_indent, | |||
| [do_indent](auto& os, auto& value) | |||
| { | |||
| using namespace ::utl; | |||
| if (do_indent) | |||
| os << indent; | |||
| os << utl::to_string(value); | |||
| }); | |||
| } | |||
| }; | |||
| constexpr decltype(auto) print_container = print_container_builder { }; | |||
| } | |||
| end_namespace_cpphibernate_misc | |||
| @@ -0,0 +1,26 @@ | |||
| #pragma once | |||
| #include <cpphibernate/config.h> | |||
| namespace cpphibernate | |||
| { | |||
| namespace __impl | |||
| { | |||
| /** | |||
| * @brief Helper type to build print container. | |||
| */ | |||
| template<typename X, typename = void> | |||
| struct print_container_builder; | |||
| } | |||
| /** | |||
| * @brief Predicate to create print container from the passed attributes. | |||
| */ | |||
| constexpr decltype(auto) make_print_container = mp::generic_predicate<__impl::print_container_builder> { }; | |||
| } | |||
| #include "print_container.inl" | |||
| @@ -0,0 +1,116 @@ | |||
| #pragma once | |||
| #include <cppcore/misc/indent.h> | |||
| #include "print_container.h" | |||
| namespace cpphibernate | |||
| { | |||
| namespace __impl | |||
| { | |||
| /* print_container */ | |||
| template<typename T_container, typename T_func> | |||
| struct print_container | |||
| { | |||
| using container_type = T_container; | |||
| using func_type = T_func; | |||
| container_type container; | |||
| bool do_indent; | |||
| func_type func; | |||
| inline void print(std::ostream& os) const | |||
| { | |||
| using namespace ::cppcore; | |||
| auto beg = std::begin(container); | |||
| auto end = std::end (container); | |||
| if (beg != end) | |||
| { | |||
| if (do_indent) | |||
| { | |||
| os << indent << "[" | |||
| << incindent; | |||
| } | |||
| else | |||
| { | |||
| os << "["; | |||
| } | |||
| size_t index = 0; | |||
| for (auto it = beg; it != end; ++it) | |||
| { | |||
| if (index++) | |||
| os << ","; | |||
| if (!do_indent) | |||
| os << " "; | |||
| func(os, *it); | |||
| } | |||
| if (do_indent) | |||
| { | |||
| os << decindent | |||
| << indent << "]"; | |||
| } | |||
| else | |||
| { | |||
| os << " ]"; | |||
| } | |||
| } | |||
| else | |||
| { | |||
| os << "[ ]"; | |||
| } | |||
| } | |||
| }; | |||
| /* print_container_builder */ | |||
| template<typename X, typename> | |||
| struct print_container_builder | |||
| { | |||
| template<typename... T_args> | |||
| static constexpr decltype(auto) apply(T_args&&...) | |||
| { static_assert(sizeof...(T_args) == -1, "Invalid parameters for make_print_container(...)!"); } | |||
| }; | |||
| template<typename T_container, typename T_func> | |||
| struct print_container_builder<mp::list<T_container, bool, T_func>, void> | |||
| { | |||
| static constexpr decltype(auto) apply(T_container&& container, bool do_indent, T_func&& func) | |||
| { | |||
| using print_container_type = print_container<T_container, T_func>; | |||
| return print_container_type { | |||
| std::forward<T_container>(container), | |||
| do_indent, | |||
| std::forward<T_func>(func), | |||
| }; | |||
| } | |||
| }; | |||
| template<typename T_container> | |||
| struct print_container_builder<mp::list<T_container, bool>, void> | |||
| { | |||
| static constexpr decltype(auto) apply(T_container&& container, bool do_indent) | |||
| { | |||
| using namespace ::cppcore; | |||
| make_print_container( | |||
| std::forward<T_container>(container), | |||
| do_indent, | |||
| [do_indent](auto& os, auto& value) | |||
| { | |||
| using namespace ::cppcore; | |||
| if (do_indent) | |||
| os << indent; | |||
| os << to_string(value); | |||
| }); | |||
| } | |||
| }; | |||
| } | |||
| } | |||
| @@ -0,0 +1,20 @@ | |||
| #pragma once | |||
| #include <iostream> | |||
| #include <cpphibernate/config.h> | |||
| namespace std | |||
| { | |||
| template<typename T_char, typename T_traits, typename X> | |||
| inline auto operator <<(basic_ostream<T_char, T_traits>& os, X&& x) | |||
| -> ::cppmp::enable_if_t< | |||
| ::cppmp::is_valid_v<decltype(std::forward<X>(x).print(os))>, | |||
| basic_ostream<T_char, T_traits>&> | |||
| { | |||
| std::forward<X>(x).print(os); | |||
| return os; | |||
| } | |||
| } | |||
| @@ -0,0 +1,34 @@ | |||
| #pragma once | |||
| #include <cpphibernate/config.h> | |||
| namespace cpphibernate | |||
| { | |||
| /** | |||
| * @brief Evaluates to the basic dataset type (containers are removed). | |||
| */ | |||
| template<typename T> | |||
| struct real_dataset; | |||
| /** | |||
| * @brief Basic dataset type (containers are removed). | |||
| */ | |||
| template<typename T> | |||
| using real_dataset_t = typename real_dataset<T>::type; | |||
| /** | |||
| * @brief Extract the type stored in an type definition . | |||
| */ | |||
| template<typename T> | |||
| using unwrap_t = typename T::type; | |||
| /** | |||
| * @brief Extract the decayed type in an type definition. | |||
| */ | |||
| template<typename T> | |||
| using decay_unwrap_t = typename mp::decay_t<T>::type; | |||
| } | |||
| #include "type_helper.inl" | |||
| @@ -0,0 +1,53 @@ | |||
| #pragma once | |||
| #include "type_helper.h" | |||
| #include <list> | |||
| #include <vector> | |||
| #include <memory> | |||
| #include <cppcore/misc/nullable.h> | |||
| #include <cpphibernate/config.h> | |||
| namespace cpphibernate | |||
| { | |||
| namespace __impl | |||
| { | |||
| /* real_dataset_impl */ | |||
| template<typename T, typename = void> | |||
| struct real_dataset_impl | |||
| { using type = T; }; | |||
| template<typename T> | |||
| struct real_dataset_impl<cppcore::nullable<T>, void> | |||
| { using type = typename real_dataset_impl<T>::type; }; | |||
| template<typename T, typename... T_args> | |||
| struct real_dataset_impl<std::unique_ptr<T, T_args...>, void> | |||
| { using type = typename real_dataset_impl<T>::type; }; | |||
| template<typename T> | |||
| struct real_dataset_impl<std::shared_ptr<T>, void> | |||
| { using type = typename real_dataset_impl<T>::type; }; | |||
| template<typename T, typename... T_args> | |||
| struct real_dataset_impl<std::list<T, T_args...>, void> | |||
| { using type = typename real_dataset_impl<T>::type; }; | |||
| template<typename T, typename... T_args> | |||
| struct real_dataset_impl<std::vector<T, T_args...>, void> | |||
| { using type = typename real_dataset_impl<T>::type; }; | |||
| } | |||
| /* real_dataset */ | |||
| template<typename T> | |||
| struct real_dataset | |||
| : public __impl::real_dataset_impl<T> | |||
| { }; | |||
| } | |||
| @@ -1,44 +0,0 @@ | |||
| #pragma once | |||
| #include <list> | |||
| #include <vector> | |||
| #include <memory> | |||
| #include <cpphibernate/config.h> | |||
| #include <cpputils/container/nullable.h> | |||
| beg_namespace_cpphibernate_misc | |||
| { | |||
| template<typename T> | |||
| using unwrap_t = typename T::type; | |||
| template<typename T> | |||
| using decay_unwrap_t = typename mp::decay_t<T>::type; | |||
| namespace __impl | |||
| { | |||
| struct wrap_t | |||
| { | |||
| template<typename T> | |||
| constexpr decltype(auto) operator()(T) const noexcept | |||
| { return hana::type_c<T>; } | |||
| }; | |||
| struct unwrapped_t | |||
| { | |||
| template<typename T> | |||
| constexpr decltype(auto) operator()(T) const noexcept | |||
| { return unwrap_t<T> { }; } | |||
| }; | |||
| } | |||
| constexpr decltype(auto) wrap = __impl::wrap_t { }; | |||
| constexpr decltype(auto) unwrap = __impl::unwrapped_t { }; | |||
| } | |||
| end_namespace_cpphibernate_misc | |||
| @@ -1,8 +0,0 @@ | |||
| #pragma once | |||
| #include <cpphibernate/modifier/limit.h> | |||
| #include <cpphibernate/modifier/modifier.h> | |||
| #include <cpphibernate/modifier/modifiers.h> | |||
| #include <cpphibernate/modifier/offset.h> | |||
| #include <cpphibernate/modifier/order_by.h> | |||
| #include <cpphibernate/modifier/where.h> | |||
| @@ -1,12 +1,11 @@ | |||
| #pragma once | |||
| #include <cpphibernate/schema/attribute.h> | |||
| #include <cpphibernate/schema/attributes.h> | |||
| #include <cpphibernate/schema/field.h> | |||
| #include <cpphibernate/schema/fields.h> | |||
| #include <cpphibernate/schema/getter.h> | |||
| #include <cpphibernate/schema/macros.h> | |||
| #include <cpphibernate/schema/schema.h> | |||
| #include <cpphibernate/schema/setter.h> | |||
| #include <cpphibernate/schema/table.h> | |||
| #include <cpphibernate/schema/tables.h> | |||
| #include "schema/macros.h" | |||
| #include "schema/attribute.h" | |||
| #include "schema/attributes.h" | |||
| #include "schema/field.h" | |||
| #include "schema/fields.h" | |||
| #include "schema/table.h" | |||
| #include "schema/tables.h" | |||
| #include "schema/schema.h" | |||
| @@ -1,23 +1,31 @@ | |||
| #pragma once | |||
| #include <cpphibernate/config.h> | |||
| #include <cpphibernate/misc/equality_compare.h> | |||
| beg_namespace_cpphibernate_schema | |||
| { | |||
| namespace cpphibernate { | |||
| namespace schema { | |||
| namespace __impl | |||
| { | |||
| /* attribute_t */ | |||
| /** | |||
| * @brief Tag class to mark attribute types. | |||
| */ | |||
| struct tag_attribute | |||
| { }; | |||
| /** | |||
| * @brief Attribute implementation. | |||
| */ | |||
| template<typename T_inner> | |||
| struct attribute_t | |||
| : public T_inner | |||
| , public tag_attribute | |||
| , public tag_equality_comparable<tag_attribute> | |||
| { | |||
| using inner_type = T_inner; | |||
| using this_type = attribute_t<inner_type>; | |||
| cpphibernate_equality_comparable(); | |||
| }; | |||
| struct hex_t { static constexpr decltype(auto) name = "hex"; }; | |||
| @@ -29,32 +37,39 @@ beg_namespace_cpphibernate_schema | |||
| namespace attribute | |||
| { | |||
| using hex_type = __impl::attribute_t<__impl::hex_t>; | |||
| using compress_type = __impl::attribute_t<__impl::compress_t>; | |||
| using primary_key_type = __impl::attribute_t<__impl::primary_key_t>; | |||
| using hex_type = __impl::attribute_t<__impl::hex_t>; | |||
| using compress_type = __impl::attribute_t<__impl::compress_t>; | |||
| using primary_key_type = __impl::attribute_t<__impl::primary_key_t>; | |||
| /** value is stored as hexadecimal string, and will be converted to its binary form on read */ | |||
| constexpr hex_type hex { }; | |||
| /** | |||
| * @brief Attribute to indicate that the value is stored as hexadecimal string. | |||
| */ | |||
| constexpr hex_type hex { }; | |||
| /** value is stored as compressed binary, and will be uncompressed on read */ | |||
| constexpr compress_type compress { }; | |||
| /** | |||
| * @brief Attribute to indicate that the value is stored compressed. | |||
| */ | |||
| constexpr compress_type compress { }; | |||
| /** this value represents a primary key (it must be stored in the dataset to be able to do the operations on the database) */ | |||
| constexpr primary_key_type primary_key { }; | |||
| /** | |||
| * @brief Attribute to indicate that the value is the primary key field. | |||
| */ | |||
| constexpr primary_key_type primary_key { }; | |||
| } | |||
| /* meta */ | |||
| /** | |||
| * @brief Evaluates to true_t if the passed type is an attribute type. | |||
| */ | |||
| template<typename T> | |||
| struct is_attribute; | |||
| /** | |||
| * @brief Is true if the passed type is an attribute, false otherwise. | |||
| */ | |||
| template<typename T> | |||
| struct is_attribute | |||
| : public mp::is_specialization_of<T, __impl::attribute_t> | |||
| { }; | |||
| constexpr bool is_attribute_v = is_attribute<T>::value; | |||
| template<typename... T> | |||
| struct all_are_attribures | |||
| : public mp::all_true<is_attribute<T>::value...> | |||
| { }; | |||
| } } | |||
| } | |||
| end_namespace_cpphibernate_schema | |||
| #include "attribute.inl" | |||
| @@ -0,0 +1,15 @@ | |||
| #pragma once | |||
| #include "attribute.h" | |||
| namespace cpphibernate { | |||
| namespace schema { | |||
| /* is_attribute */ | |||
| template<typename T> | |||
| struct is_attribute | |||
| : public mp::is_base_of<__impl::tag_attribute, T> | |||
| { }; | |||
| } } | |||
| @@ -1,73 +1,39 @@ | |||
| #pragma once | |||
| #include <cpphibernate/config.h> | |||
| #include <cpphibernate/misc.h> | |||
| #include <cpphibernate/schema/attribute.h> | |||
| beg_namespace_cpphibernate_schema | |||
| { | |||
| namespace cpphibernate { | |||
| namespace schema { | |||
| namespace __impl | |||
| { | |||
| /* attributes_t */ | |||
| template<typename... T_attributes> | |||
| using attributes_t = hana::tuple<T_attributes...>; | |||
| /* is_attributes_impl */ | |||
| /** | |||
| * @brief Helper type to build attributes. | |||
| */ | |||
| template<typename T, typename = void> | |||
| struct is_attributes_impl | |||
| : mp::c_false_t | |||
| { }; | |||
| template<typename... T> | |||
| struct is_attributes_impl<attributes_t<T...>, mp::enable_if<all_are_attribures<T...>>> | |||
| : mp::c_true_t | |||
| { }; | |||
| struct attributes_builder; | |||
| } | |||
| /* meta */ | |||
| /** | |||
| * @brief Evaluates to true_t if the passed type is a attributes type. | |||
| */ | |||
| template<typename T> | |||
| struct is_attributes | |||
| : public __impl::is_attributes_impl<T> | |||
| { }; | |||
| /* operations */ | |||
| namespace __impl | |||
| { | |||
| struct is_attributes; | |||
| /* attributes_make_impl */ | |||
| template<typename T, typename = void> | |||
| struct attributes_make_impl | |||
| { | |||
| template<typename... T_args> | |||
| static constexpr decltype(auto) apply(T_args&&...) | |||
| { static_assert(sizeof...(T_args) == -1, "Invalid parameters for hibernate::schema::attributes::make(...)!"); } | |||
| }; | |||
| template<typename... T> | |||
| struct attributes_make_impl<mp::list<T...>, mp::enable_if_c< | |||
| all_are_attribures<mp::decay_t<T>...>::value>> | |||
| { | |||
| template<typename... T_args> | |||
| static constexpr decltype(auto) apply(T_args&&...) | |||
| { return attributes_t<mp::decay_t<T_args>...> { }; } | |||
| }; | |||
| } | |||
| namespace attributes | |||
| { | |||
| /** | |||
| * @brief Is true if the passed type is an attributes type, false otherwise. | |||
| */ | |||
| template<typename T> | |||
| constexpr bool is_attributes_v = is_attributes<T>::value; | |||
| constexpr decltype(auto) make = misc::make_generic_predicate<__impl::attributes_make_impl> { }; | |||
| /** | |||
| * @brief Predicate to create an attributes object from the passed attributes. | |||
| */ | |||
| constexpr decltype(auto) make_attributes = mp::generic_predicate<__impl::attributes_builder> { }; | |||
| } | |||
| } } | |||
| } | |||
| end_namespace_cpphibernate_schema | |||
| #include "attributes.inl" | |||
| @@ -0,0 +1,62 @@ | |||
| #pragma once | |||
| #include "attributes.h" | |||
| namespace cpphibernate { | |||
| namespace schema { | |||
| namespace __impl | |||
| { | |||
| /* attributes_t */ | |||
| template<typename... T_attributes> | |||
| using attributes_t = hana::basic_tuple<T_attributes...>; | |||
| /* attributes_builder */ | |||
| template<typename T, typename> | |||
| struct attributes_builder | |||
| { | |||
| template<typename... T_args> | |||
| static constexpr decltype(auto) apply(T_args&&...) | |||
| { static_assert(sizeof...(T_args) == -1, "Invalid parameters for make_attributes(...)!"); } | |||
| }; | |||
| template<typename... T> | |||
| struct attributes_builder< | |||
| mp::list<T...>, | |||
| mp::enable_if_t< | |||
| mp::is_true_v<is_attribute_v<mp::decay_t<T>>...>>> | |||
| { | |||
| static constexpr decltype(auto) apply(T&&...) | |||
| { | |||
| using attributes_type = attributes_t<mp::decay_t<T>...>; | |||
| return attributes_type { }; | |||
| } | |||
| }; | |||
| /* is_attributes_impl */ | |||
| template<typename T, typename = void> | |||
| struct is_attributes_impl | |||
| : mp::false_t | |||
| { }; | |||
| template<typename... T> | |||
| struct is_attributes_impl< | |||
| attributes_t<T...>, | |||
| mp::enable_if_t<mp::is_true_v<is_attribute_v<mp::decay_t<T>>...>>> | |||
| : mp::true_t | |||
| { }; | |||
| } | |||
| /* is_attributes */ | |||
| template<typename T> | |||
| struct is_attributes | |||
| : public __impl::is_attributes_impl<T> | |||
| { }; | |||
| } } | |||
| @@ -1,126 +1,38 @@ | |||
| #pragma once | |||
| #include <cpphibernate/misc.h> | |||
| #include <cpphibernate/config.h> | |||
| #include <cpphibernate/schema/getter.h> | |||
| #include <cpphibernate/schema/setter.h> | |||
| #include <cpphibernate/schema/attributes.h> | |||
| #include <cpputils/misc/indent.h> | |||
| #include <cpputils/misc/type_helper.h> | |||
| beg_namespace_cpphibernate_schema | |||
| { | |||
| namespace cpphibernate { | |||
| namespace schema { | |||
| namespace __impl | |||
| { | |||
| /* field_t */ | |||
| template<typename T_name, typename T_getter, typename T_setter, typename T_attributes> | |||
| struct field_t | |||
| { | |||
| using name_type = T_name; | |||
| using getter_type = T_getter; | |||
| using setter_type = T_setter; | |||
| using attributes_type = T_attributes; | |||
| using this_type = field_t<name_type, getter_type, setter_type, attributes_type>; | |||
| name_type name; | |||
| getter_type getter; | |||
| setter_type setter; | |||
| attributes_type attributes; | |||
| constexpr field_t( | |||
| T_name&& p_name, | |||
| T_getter&& p_getter, | |||
| T_setter&& p_setter, | |||
| T_attributes&& p_attributes) | |||
| : name (std::forward<T_name> (p_name)) | |||
| , getter (std::forward<T_getter> (p_getter)) | |||
| , setter (std::forward<T_setter> (p_setter)) | |||
| , attributes (std::forward<T_attributes>(p_attributes)) | |||
| { } | |||
| cpphibernate_copyable(field_t, delete); | |||
| cpphibernate_moveable(field_t, default); | |||
| cpphibernate_equality_comparable(); | |||
| inline void print(std::ostream& os) const | |||
| { | |||
| using namespace ::utl; | |||
| using value_type = typename mp::decay_t<getter_type>::value_type; | |||
| using dataset_type = misc::real_dataset_t<value_type>; | |||
| size_t index = 0; | |||
| os << indent << '{' | |||
| << incindent | |||
| << indent << "\"name\": \"" << name << "\"," | |||
| << indent << "\"value_type\": \"" << utl::type_helper<value_type>::name() << "\"" | |||
| << indent << "\"dataset_type\": \"" << utl::type_helper<dataset_type>::name() << "\"" | |||
| << indent << "\"attributes\": " | |||
| << indent << '[' | |||
| << incindent; | |||
| hana::for_each(attributes, [&](auto& attrib){ | |||
| if (index++ > 0) os << ","; | |||
| os << indent << attrib.name; | |||
| }); | |||
| os << decindent | |||
| << indent << ']' | |||
| << decindent | |||
| << indent << '}'; | |||
| } | |||
| }; | |||
| /** | |||
| * @brief Helper type to build field objects. | |||
| */ | |||
| template<typename X, typename = void> | |||
| struct field_builder; | |||
| } | |||
| /* meta */ | |||
| /** | |||
| * @brief Evaluates to true_t if the passed type is a field type. | |||
| */ | |||
| template<typename T> | |||
| struct is_field | |||
| : public mp::is_specialization_of<T, __impl::field_t> | |||
| { }; | |||
| template<typename... T> | |||
| struct all_are_fields | |||
| : public mp::all_true<is_field<T>::value...> | |||
| { }; | |||
| /* operations */ | |||
| namespace __impl | |||
| { | |||
| /* field_make_impl */ | |||
| template<typename X, typename = void> | |||
| struct field_make_impl | |||
| { | |||
| template <typename ...T_args> | |||
| static constexpr decltype(auto) apply(T_args&&... args) | |||
| { static_assert(sizeof...(args) == -1, "Invalid parameters for hibernate::schema::field::make(...)!"); } | |||
| }; | |||
| template<typename T_name, typename T_getter, typename T_setter, typename T_attributes> | |||
| struct field_make_impl<mp::list<T_name, T_getter, T_setter, T_attributes>, mp::enable_if_c< | |||
| is_getter<mp::decay_t<T_getter>>::value | |||
| && is_setter<mp::decay_t<T_setter>>::value | |||
| && is_attributes<mp::decay_t<T_attributes>>::value>> | |||
| { | |||
| using field_type = field_t<T_name, T_getter, T_setter, T_attributes>; | |||
| struct is_field; | |||
| static constexpr decltype(auto) apply(T_name&& name, T_getter&& getter, T_setter&& setter, T_attributes&& attributes) | |||
| { return field_type(std::forward<T_name>(name), std::forward<T_getter>(getter), std::forward<T_setter>(setter), std::forward<T_attributes>(attributes)); } | |||
| }; | |||
| } | |||
| namespace field | |||
| { | |||
| /** | |||
| * @brief Is true if the passed type is an attributes type, false otherwise. | |||
| */ | |||
| template<typename T> | |||
| constexpr bool is_field_v = is_field<T>::value; | |||
| constexpr decltype(auto) make = misc::make_generic_predicate<__impl::field_make_impl> { }; | |||
| /** | |||
| * @brief Predicate to create an field object from the passed attributes. | |||
| */ | |||
| constexpr decltype(auto) make_field = mp::generic_predicate<__impl::field_builder> { }; | |||
| } | |||
| } } | |||
| } | |||
| end_namespace_cpphibernate_schema | |||
| #include "field.inl" | |||
| @@ -0,0 +1,132 @@ | |||
| #pragma once | |||
| #include <cppcore/misc/indent.h> | |||
| #include <cppcore/misc/type_helper.h> | |||
| #include <cpphibernate/misc/type_helper.h> | |||
| #include "field.h" | |||
| namespace cpphibernate { | |||
| namespace schema { | |||
| namespace __impl | |||
| { | |||
| /* tag_field */ | |||
| struct tag_field | |||
| { }; | |||
| /* field_t */ | |||
| template<typename T_name, typename T_getter, typename T_setter, typename T_attributes> | |||
| struct field_t | |||
| : public tag_field | |||
| , public tag_equality_comparable<tag_field> | |||
| { | |||
| using name_type = T_name; | |||
| using getter_type = T_getter; | |||
| using setter_type = T_setter; | |||
| using attributes_type = T_attributes; | |||
| using this_type = field_t<name_type, getter_type, setter_type, attributes_type>; | |||
| name_type name; | |||
| getter_type getter; | |||
| setter_type setter; | |||
| attributes_type attributes; | |||
| constexpr field_t( | |||
| T_name&& p_name, | |||
| T_getter&& p_getter, | |||
| T_setter&& p_setter, | |||
| T_attributes&& p_attributes) | |||
| : name (std::forward<T_name> (p_name)) | |||
| , getter (std::forward<T_getter> (p_getter)) | |||
| , setter (std::forward<T_setter> (p_setter)) | |||
| , attributes (std::forward<T_attributes>(p_attributes)) | |||
| { } | |||
| constexpr field_t(field_t&&) = default; | |||
| constexpr field_t(const field_t&) = delete; | |||
| constexpr field_t& operator = (field_t&&) = default; | |||
| constexpr field_t& operator = (const field_t&) = delete; | |||
| inline void print(std::ostream& os) const | |||
| { | |||
| using namespace ::cppcore; | |||
| using value_type = typename mp::decay_t<getter_type>::value_type; | |||
| using dataset_type = real_dataset_t<value_type>; | |||
| size_t index = 0; | |||
| os << indent << '{' | |||
| << incindent | |||
| << indent << "\"name\": \"" << name << "\"," | |||
| << indent << "\"value_type\": \"" << type_helper<value_type>::name() << "\"" | |||
| << indent << "\"dataset_type\": \"" << type_helper<dataset_type>::name() << "\"" | |||
| << indent << "\"attributes\": " | |||
| << indent << '[' | |||
| << incindent; | |||
| hana::for_each(attributes, [&](auto& attrib){ | |||
| if (index++ > 0) os << ","; | |||
| os << indent << '"' << attrib.name << '"'; | |||
| }); | |||
| os << decindent | |||
| << indent << ']' | |||
| << decindent | |||
| << indent << '}'; | |||
| } | |||
| }; | |||
| /* field_builder */ | |||
| template<typename X, typename> | |||
| struct field_builder | |||
| { | |||
| template<typename... T_args> | |||
| static constexpr decltype(auto) apply(T_args&&...) | |||
| { static_assert(sizeof...(T_args) == -1, "Invalid parameters for make_field(...)!"); } | |||
| }; | |||
| template<typename T_name, typename T_getter, typename T_setter, typename T_attributes> | |||
| struct field_builder< | |||
| mp::list<T_name, T_getter, T_setter, T_attributes>, | |||
| mp::enable_if_t< | |||
| true | |||
| // && mp::is_getter_v<mp::decay_t<T_getter>> | |||
| // && mp::is_setter_v<mp::decay_t<T_setter>> | |||
| // && is_attributes_v<mp::decay_t<T_attributes>> | |||
| >> | |||
| { | |||
| using name_type = T_name; | |||
| using getter_type = T_getter; | |||
| using setter_type = T_setter; | |||
| using attributes_type = T_attributes; | |||
| using field_type = field_t<name_type, getter_type, setter_type, attributes_type>; | |||
| static constexpr decltype(auto) apply( | |||
| name_type&& name, | |||
| getter_type&& getter, | |||
| setter_type&& setter, | |||
| attributes_type&& attributes) | |||
| { | |||
| return field_type( | |||
| std::forward<name_type> (name), | |||
| std::forward<getter_type> (getter), | |||
| std::forward<setter_type> (setter), | |||
| std::forward<attributes_type> (attributes)); | |||
| } | |||
| }; | |||
| } | |||
| /* is_field */ | |||
| template<typename T> | |||
| struct is_field | |||
| : public mp::is_base_of<__impl::tag_field, T> | |||
| { }; | |||
| } } | |||
| @@ -1,72 +1,39 @@ | |||
| #pragma once | |||
| #include <cpphibernate/config.h> | |||
| #include <cpphibernate/misc/general.h> | |||
| #include <cpphibernate/schema/field.h> | |||
| beg_namespace_cpphibernate_schema | |||
| { | |||
| namespace cpphibernate { | |||
| namespace schema { | |||
| namespace __impl | |||
| { | |||
| /* fields_t */ | |||
| template<typename... T_fields> | |||
| using fields_t = hana::tuple<T_fields...>; | |||
| /* is_fields_impl */ | |||
| /** | |||
| * @brief Helper type to build fields. | |||
| */ | |||
| template<typename T, typename = void> | |||
| struct is_fields_impl | |||
| : public mp::c_false_t | |||
| { }; | |||
| template<typename... T> | |||
| struct is_fields_impl<fields_t<T...>, mp::enable_if<all_are_fields<T...>>> | |||
| : public mp::c_true_t | |||
| { }; | |||
| struct fields_builder; | |||
| } | |||
| /* meta */ | |||
| /** | |||
| * @brief Evaluates to true_t if the passed type is a fields type. | |||
| */ | |||
| template<typename T> | |||
| struct is_fields : | |||
| public __impl::is_fields_impl<T> | |||
| { }; | |||
| /* operations */ | |||
| namespace __impl | |||
| { | |||
| struct is_fields; | |||
| /* fields_make_impl */ | |||
| template <typename T, typename = void> | |||
| struct fields_make_impl | |||
| { | |||
| template <typename ...T_args> | |||
| static constexpr decltype(auto) apply(T_args&&... args) | |||
| { static_assert(sizeof...(args) == -1, "Invalid parameters for hibernate::schema::fields::make(...)!"); } | |||
| }; | |||
| template<typename... T> | |||
| struct fields_make_impl<mp::list<T...>, mp::enable_if<all_are_fields<T...>>> | |||
| { | |||
| template <typename ...T_args> | |||
| static constexpr decltype(auto) apply(T_args&&... args) | |||
| { return fields_t<T_args...>(std::forward<T_args>(args)...); } | |||
| }; | |||
| } | |||
| namespace fields | |||
| { | |||
| /** | |||
| * @brief Is true if the passed type is an fields type, false otherwise. | |||
| */ | |||
| template<typename T> | |||
| constexpr bool is_fields_v = is_fields<T>::value; | |||
| constexpr decltype(auto) make = misc::make_generic_predicate<__impl::fields_make_impl> { }; | |||
| /** | |||
| * @brief Predicate to create an fields object from the passed fields. | |||
| */ | |||
| constexpr decltype(auto) make_fields = mp::generic_predicate<__impl::fields_builder> { }; | |||
| } | |||
| } } | |||
| } | |||
| end_namespace_cpphibernate_schema | |||
| #include "fields.inl" | |||
| @@ -0,0 +1,63 @@ | |||
| #pragma once | |||
| #include "fields.h" | |||
| namespace cpphibernate { | |||
| namespace schema { | |||
| namespace __impl | |||
| { | |||
| /* fields_t */ | |||
| template<typename... T_fields> | |||
| using fields_t = hana::basic_tuple<T_fields...>; | |||
| /* fields_builder */ | |||
| template<typename T, typename> | |||
| struct fields_builder | |||
| { | |||
| template<typename... T_args> | |||
| static constexpr decltype(auto) apply(T_args&&...) | |||
| { static_assert(sizeof...(T_args) == -1, "Invalid parameters for make_fields(...)!"); } | |||
| }; | |||
| template<typename... T> | |||
| struct fields_builder< | |||
| mp::list<T...>, | |||
| mp::enable_if_t<mp::is_true_v< | |||
| is_field_v<mp::decay_t<T>>...>>> | |||
| { | |||
| template<typename... T_args> | |||
| static constexpr decltype(auto) apply(T_args&&... args) | |||
| { | |||
| using fields_type = fields_t<T_args...>; | |||
| return fields_type(std::forward<T_args>(args)...); | |||
| } | |||
| }; | |||
| /* is_fields_impl */ | |||
| template<typename T, typename = void> | |||
| struct is_fields_impl | |||
| : mp::false_t | |||
| { }; | |||
| template<typename... T> | |||
| struct is_fields_impl< | |||
| fields_t<T...>, | |||
| mp::enable_if_t<mp::is_true_v<is_field_v<mp::decay_t<T>>...>>> | |||
| : mp::true_t | |||
| { }; | |||
| } | |||
| /* is_fields */ | |||
| template<typename T> | |||
| struct is_fields | |||
| : public __impl::is_fields_impl<T> | |||
| { }; | |||
| } } | |||
| @@ -1,192 +0,0 @@ | |||
| #pragma once | |||
| #include <cpphibernate/config.h> | |||
| #include <cpphibernate/misc/general.h> | |||
| beg_namespace_cpphibernate_schema | |||
| { | |||
| namespace __impl | |||
| { | |||
| /* getter_t */ | |||
| template<typename T_dataset, typename T_value> | |||
| struct getter_t | |||
| { | |||
| using dataset_type = T_dataset; | |||
| using value_type = T_value; | |||
| }; | |||
| /* getter_member_var_t */ | |||
| template<typename T_dataset, typename T_value, typename T_member> | |||
| struct getter_member_var_t | |||
| : public getter_t<T_dataset, T_value> | |||
| { | |||
| using base_type = getter_t<T_dataset, T_value>; | |||
| using dataset_type = typename base_type::dataset_type; | |||
| using value_type = typename base_type::value_type; | |||
| using member_type = T_member; | |||
| member_type member; | |||
| template<typename X_member> | |||
| constexpr getter_member_var_t(X_member&& p_member) | |||
| : member(std::forward<X_member>(p_member)) | |||
| { } | |||
| cpphibernate_copyable(getter_member_var_t, delete); | |||
| cpphibernate_moveable(getter_member_var_t, default); | |||
| template<typename X_dataset> | |||
| constexpr decltype(auto) operator()(X_dataset&& data) const | |||
| { return std::forward<X_dataset>(data).*member; } | |||
| }; | |||
| /* getter_member_func_t */ | |||
| template<typename T_dataset, typename T_value, typename T_member> | |||
| struct getter_member_func_t | |||
| : public getter_t<T_dataset, T_value> | |||
| { | |||
| using base_type = getter_t<T_dataset, T_value>; | |||
| using dataset_type = typename base_type::dataset_type; | |||
| using value_type = typename base_type::value_type; | |||
| using member_type = T_member; | |||
| member_type member; | |||
| template<typename X_member> | |||
| constexpr getter_member_func_t(X_member&& p_member) | |||
| : member(std::forward<X_member>(p_member)) | |||
| { }; | |||
| cpphibernate_copyable(getter_member_func_t, delete); | |||
| cpphibernate_moveable(getter_member_func_t, default); | |||
| template<typename X_dataset> | |||
| constexpr decltype(auto) operator()(X_dataset&& data) const | |||
| { return (std::forward<X_dataset>(data).*member)(); } | |||
| }; | |||
| /* getter_lambda_t */ | |||
| template<typename T_lambda, typename T_dataset, typename T_value> | |||
| struct getter_lambda_t | |||
| : public getter_t<T_dataset, T_value> | |||
| { | |||
| using base_type = getter_t<T_dataset, T_value>; | |||
| using dataset_type = typename base_type::dataset_type; | |||
| using value_type = typename base_type::value_type; | |||
| using lambda_type = T_lambda; | |||
| lambda_type lambda; | |||
| template<typename X_lambda> | |||
| constexpr getter_lambda_t(X_lambda&& p_lambda) | |||
| : lambda(std::forward<X_lambda>(p_lambda)) | |||
| { } | |||
| cpphibernate_copyable(getter_lambda_t, delete); | |||
| cpphibernate_moveable(getter_lambda_t, default); | |||
| template<typename X_dataset> | |||
| constexpr decltype(auto) operator()(X_dataset&& data) const | |||
| { return lambda(std::forward<X_dataset>(data)); } | |||
| }; | |||
| /* is_getter_impl */ | |||
| template<typename T, typename = void> | |||
| struct is_getter_impl | |||
| : public mp::c_false_t | |||
| { }; | |||
| template<typename T> | |||
| struct is_getter_impl<T, mp::enable_if< | |||
| mp::is_base_of<getter_t<typename T::dataset_type, typename T::value_type>, T>>> | |||
| : public mp::c_true_t | |||
| { }; | |||
| } | |||
| /* meta */ | |||
| template<typename T> | |||
| struct is_getter : | |||
| public __impl::is_getter_impl<T> | |||
| { }; | |||
| /* make */ | |||
| template<typename T_dataset, typename T_value> | |||
| constexpr decltype(auto) make_getter_member_var(T_value T_dataset::* member) | |||
| { | |||
| using getter_type = __impl::getter_member_var_t<T_dataset, T_value, T_value T_dataset::*>; | |||
| return getter_type(member); | |||
| } | |||
| template<typename T_dataset, typename T_value> | |||
| constexpr decltype(auto) make_getter_member_func(T_value (T_dataset::*member)()) | |||
| { | |||
| using getter_type = __impl::getter_member_func_t<T_dataset, T_value, T_value (T_dataset::*)()>; | |||
| return getter_type(member); | |||
| } | |||
| template<typename T_dataset, typename T_value> | |||
| constexpr decltype(auto) make_getter_member_func(T_value (T_dataset::*member)() const) | |||
| { | |||
| using getter_type = __impl::getter_member_func_t<const T_dataset, T_value, T_value (T_dataset::*)() const>; | |||
| return getter_type(member); | |||
| } | |||
| template<typename T_lambda, typename T_wrapped_dataset, typename T_wrapped_value> | |||
| constexpr decltype(auto) make_getter_lambda(T_lambda&& lambda, T_wrapped_dataset&&, T_wrapped_value&&) | |||
| { | |||
| using getter_type = __impl::getter_lambda_t<T_lambda, misc::decay_unwrap_t<T_wrapped_dataset>, misc::decay_unwrap_t<T_wrapped_value>>; | |||
| return getter_type(std::forward<T_lambda>(lambda)); | |||
| } | |||
| /* operations */ | |||
| namespace __impl | |||
| { | |||
| /* getter_make_impl */ | |||
| struct getter_make_impl | |||
| { | |||
| template<typename T_dataset, typename T_value> | |||
| constexpr decltype(auto) operator()(T_value T_dataset::*member) const | |||
| { return make_getter_member_var(member); } | |||
| template<typename T_dataset, typename T_value> | |||
| constexpr decltype(auto) operator()(T_value (T_dataset::*member)(void)) const | |||
| { return make_getter_member_func(member); } | |||
| template<typename T_dataset, typename T_value> | |||
| constexpr decltype(auto) operator()(T_value (T_dataset::*member)(void) const) const | |||
| { return make_getter_member_func(member); } | |||
| template<typename T_func, typename T_dataset, typename T_value> | |||
| constexpr decltype(auto) operator()(T_func&& func, hana::type<T_dataset>&& wrapped_dataset, hana::type<T_value>&& wrapped_value) const | |||
| { return make_getter_lambda(std::forward<T_func>(func), std::forward<hana::type<T_dataset>>(wrapped_dataset), std::forward<hana::type<T_value>>(wrapped_value)); } | |||
| template<typename T_getter> | |||
| constexpr auto operator()(T_getter&& getter) const | |||
| -> mp::enable_if<is_getter<T_getter>, T_getter> | |||
| { return std::forward<T_getter>(getter); } | |||
| }; | |||
| } | |||
| namespace getter | |||
| { | |||
| constexpr decltype(auto) make = __impl::getter_make_impl { }; | |||
| } | |||
| } | |||
| end_namespace_cpphibernate_schema | |||
| @@ -1,32 +1,31 @@ | |||
| #pragma once | |||
| #include <cpphibernate/config.h> | |||
| #include <cpphibernate/types.h> | |||
| #define cpphibernate_make_string(str) \ | |||
| #str | |||
| #define cpphibernate_make_schema(p_name, ...) \ | |||
| cpphibernate::schema::make( \ | |||
| cpphibernate::schema::make_schema( \ | |||
| cpphibernate_make_string(p_name), \ | |||
| cpphibernate::schema::tables::make(__VA_ARGS__)) | |||
| cpphibernate::schema::make_tables(__VA_ARGS__)) | |||
| #define cpphibernate_make_table_name(p_name, p_type, p_id, ...) \ | |||
| cpphibernate::schema::table::make( \ | |||
| cpphibernate::schema::make_table( \ | |||
| cpphibernate_make_string(p_name), \ | |||
| boost::hana::type_c<p_type>, \ | |||
| boost::hana::size_c<p_id>, \ | |||
| cpphibernate::schema::fields::make(__VA_ARGS__)) | |||
| cpphibernate::schema::make_fields(__VA_ARGS__)) | |||
| #define cpphibernate_make_table(p_name, p_id, ...) \ | |||
| cpphibernate_make_table_name(p_name, p_name, p_id, __VA_ARGS__) | |||
| #define cpphibernate_make_field_custom(p_name, p_getter, p_setter, ...) \ | |||
| cpphibernate::schema::field::make( \ | |||
| cpphibernate::schema::make_field( \ | |||
| cpphibernate_make_string(p_name), \ | |||
| cpphibernate::schema::getter::make(p_getter), \ | |||
| cpphibernate::schema::setter::make(p_setter), \ | |||
| cpphibernate::schema::attributes::make(__VA_ARGS__)) | |||
| cpphibernate::mp::make_getter(p_getter), \ | |||
| cpphibernate::mp::make_setter(p_setter), \ | |||
| cpphibernate::schema::make_attributes(__VA_ARGS__)) | |||
| #define cpphibernate_make_field_name(p_name, p_member_ptr, ...) \ | |||
| cpphibernate_make_field_custom( \ | |||
| @@ -45,14 +44,10 @@ | |||
| #define cpphibernate_make_temp_id(p_dataset, p_value) \ | |||
| cpphibernate_make_field_custom( \ | |||
| id, \ | |||
| ::cpphibernate::schema::make_getter_lambda( \ | |||
| ::cpphibernate::mp::make_getter( \ | |||
| [](p_dataset&) { \ | |||
| return p_value { }; \ | |||
| }, \ | |||
| ::boost::hana::type_c<p_dataset>, \ | |||
| ::boost::hana::type_c<p_value>), \ | |||
| ::cpphibernate::schema::make_setter_lambda( \ | |||
| [](p_dataset&, p_value&&) { }, \ | |||
| ::boost::hana::type_c<p_dataset>, \ | |||
| ::boost::hana::type_c<p_value>), \ | |||
| }), \ | |||
| ::cpphibernate::mp::make_setter( \ | |||
| [](p_dataset&, p_value&&) { }), \ | |||
| cpphibernate::schema::attribute::primary_key) | |||
| @@ -1,252 +1,38 @@ | |||
| #pragma once | |||
| #include <cpphibernate/config.h> | |||
| #include <cpphibernate/misc/general.h> | |||
| #include <cpphibernate/schema/tables.h> | |||
| beg_namespace_cpphibernate_schema | |||
| { | |||
| namespace cpphibernate { | |||
| namespace schema { | |||
| namespace __impl | |||
| { | |||
| /* schema_t */ | |||
| template<typename T_name, typename T_tables> | |||
| struct schema_t | |||
| { | |||
| using name_type = T_name; | |||
| using tables_type = T_tables; | |||
| name_type name; | |||
| tables_type tables; | |||
| constexpr schema_t( | |||
| T_name&& p_name, | |||
| T_tables&& p_tables) | |||
| : name (std::forward<T_name> (p_name)) | |||
| , tables(std::forward<T_tables>(p_tables)) | |||
| { } | |||
| cpphibernate_copyable(schema_t, delete); | |||
| cpphibernate_moveable(schema_t, default); | |||
| inline void print(std::ostream& os) const | |||
| { | |||
| using namespace ::utl; | |||
| size_t index = 0; | |||
| os << indent << '{' | |||
| << incindent | |||
| << indent << "\"name\": \"" << name << "\"," | |||
| << indent << "\"tables\": " | |||
| << indent << '[' | |||
| << incindent; | |||
| hana::for_each(tables, [&](auto& table){ | |||
| if (index++ > 0) os << ","; | |||
| table.print(os); | |||
| }); | |||
| os << decindent | |||
| << indent << ']' | |||
| << decindent | |||
| << indent << '}'; | |||
| } | |||
| }; | |||
| /** | |||
| * @brief Helper type to build schema objects. | |||
| */ | |||
| template<typename X, typename = void> | |||
| struct schema_builder; | |||
| } | |||
| /* meta */ | |||
| /** | |||
| * @brief Evaluates to true_t if the passed type is a schema type. | |||
| */ | |||
| template<typename T> | |||
| struct is_schema : mp::is_specialization_of<T, __impl::schema_t> { }; | |||
| /* schema::make */ | |||
| namespace __impl | |||
| { | |||
| template <typename X, typename = void> | |||
| struct schema_make_impl | |||
| { | |||
| template <typename... T_args> | |||
| static constexpr decltype(auto) apply(T_args&&... args) | |||
| { static_assert(sizeof...(args) == -1, "Invalid parameters for hibernate::schema::make(...)!"); } | |||
| }; | |||
| template<typename T_name, typename T_tables> | |||
| struct schema_make_impl<mp::list<T_name, T_tables>, mp::enable_if_c< | |||
| is_tables<mp::decay_t<T_tables>>::value>> | |||
| { | |||
| static constexpr decltype(auto) apply(T_name&& name, T_tables&& tables) | |||
| { return schema_t<T_name, T_tables>(std::forward<T_name>(name), std::forward<T_tables>(tables)); } | |||
| }; | |||
| } | |||
| constexpr decltype(auto) make = misc::make_generic_predicate<__impl::schema_make_impl> { }; | |||
| /* schema::get_base_type */ | |||
| namespace __impl | |||
| { | |||
| struct schema_get_base_type_impl | |||
| { | |||
| static constexpr decltype(auto) is_base_of_pred = hana::integral(hana::metafunction<mp::is_base_of>); | |||
| struct do_fold_impl | |||
| { | |||
| template<typename T_type_1, typename T_type_2> | |||
| constexpr decltype(auto) operator()(T_type_1&& type_1, T_type_2&& type_2) const | |||
| { | |||
| auto check = hana::or_(is_base_of_pred(type_1, type_2), is_base_of_pred(type_2, type_1)); | |||
| static_assert(decltype(check)::value, "A dataset must not have more than one base class!"); | |||
| return hana::if_(is_base_of_pred(type_1, type_2), type_2, type_1); | |||
| } | |||
| }; | |||
| static constexpr decltype(auto) do_fold = do_fold_impl { }; | |||
| template<typename T_wrapped_datasets, typename T_wrapped_dataset> | |||
| static constexpr decltype(auto) get_base_types(T_wrapped_datasets&& wrapped_datasets, T_wrapped_dataset&& wrapped_dataset) | |||
| { | |||
| return hana::filter( | |||
| std::forward<T_wrapped_datasets>(wrapped_datasets), | |||
| [&](auto type){ | |||
| return hana::and_( | |||
| is_base_of_pred(type, wrapped_dataset), | |||
| hana::not_equal(type, wrapped_dataset)); | |||
| }); | |||
| } | |||
| template<typename T_schema, typename T_wrapped_dataset> | |||
| constexpr decltype(auto) operator()(T_schema&& schema, T_wrapped_dataset&& wrapped_dataset) const | |||
| { | |||
| using wrapped_datasets_type = mp::decay_t<decltype( | |||
| hana::transform( | |||
| std::declval<T_schema>().tables, | |||
| schema::table::get_wrapped_dataset))>; | |||
| auto base_types = get_base_types(wrapped_datasets_type { }, std::forward<T_wrapped_dataset>(wrapped_dataset)); | |||
| return hana::eval_if( | |||
| hana::size(base_types) <= hana::size_c<0>, | |||
| [&](auto _){ return hana::type_c<void>; }, | |||
| [&](auto _){ return hana::fold(_(base_types), do_fold); }); | |||
| } | |||
| }; | |||
| } | |||
| constexpr decltype(auto) get_base_type = __impl::schema_get_base_type_impl { }; | |||
| struct is_schema; | |||
| /* schema::get_root_base_type */ | |||
| namespace __impl | |||
| { | |||
| struct schema_get_root_base_type_impl | |||
| { | |||
| template<typename T_wrapped_dataset> | |||
| struct is_base_pred | |||
| { | |||
| using dataset_type = misc::decay_unwrap_t<T_wrapped_dataset>; | |||
| template<typename T_type> | |||
| constexpr decltype(auto) operator()(T_type&&) const | |||
| { | |||
| using type = misc::unwrap_t<T_type>; | |||
| return hana::bool_c< | |||
| std::is_base_of<type, dataset_type>::value | |||
| && !std::is_same <type, dataset_type>::value>; | |||
| } | |||
| }; | |||
| template<typename T_schema, typename T_wrapped_dataset> | |||
| constexpr decltype(auto) operator()(T_schema&& schema, T_wrapped_dataset&& wrapped_dataset) const | |||
| { | |||
| auto all_types = hana::transform( | |||
| schema.tables, | |||
| table::get_wrapped_dataset); | |||
| auto base_type = hana::find_if( | |||
| all_types, | |||
| is_base_pred<T_wrapped_dataset> { }); | |||
| return hana::eval_if( | |||
| base_type != hana::nothing, | |||
| [&](auto _){ | |||
| return schema_get_root_base_type_impl { }(schema, _(base_type).value()); | |||
| }, | |||
| [&]{ | |||
| return wrapped_dataset; | |||
| }); | |||
| } | |||
| }; | |||
| } | |||
| constexpr decltype(auto) get_root_base_type = __impl::schema_get_root_base_type_impl { }; | |||
| /* schema::get_all_derived_types */ | |||
| namespace __impl | |||
| { | |||
| struct schema_get_all_derived_types_impl | |||
| { | |||
| template<typename T_wrapped_dataset> | |||
| struct is_derived_pred | |||
| { | |||
| using dataset_type = misc::decay_unwrap_t<T_wrapped_dataset>; | |||
| template<typename T_type> | |||
| constexpr decltype(auto) operator()(T_type&&) const | |||
| { | |||
| return hana::bool_c< | |||
| std::is_base_of<dataset_type, misc::decay_unwrap_t<T_type>>::value>; | |||
| } | |||
| }; | |||
| template<typename T_schema, typename T_wrapped_dataset> | |||
| constexpr decltype(auto) operator()(T_schema&& schema, T_wrapped_dataset&&) const | |||
| { | |||
| auto all_types = hana::transform( | |||
| schema.tables, | |||
| table::get_wrapped_dataset); | |||
| auto derived_types = hana::filter( | |||
| all_types, | |||
| is_derived_pred<T_wrapped_dataset> { }); | |||
| return derived_types; | |||
| } | |||
| }; | |||
| } | |||
| constexpr decltype(auto) get_all_derived_types = __impl::schema_get_all_derived_types_impl { }; | |||
| /* schema::get_derived_types */ | |||
| namespace __impl | |||
| { | |||
| struct schema_get_derived_types_impl | |||
| { | |||
| struct has_base_impl | |||
| { | |||
| template<typename T_schema, typename T_base_type, typename T_type> | |||
| constexpr decltype(auto) operator()(T_schema&& schema, T_base_type& base_type, T_type&& type) const | |||
| { return get_base_type(schema, type) == base_type; } | |||
| }; | |||
| static constexpr decltype(auto) has_base = has_base_impl { }; | |||
| /** | |||
| * @brief Is true if the passed type is an attributes type, false otherwise. | |||
| */ | |||
| template<typename T> | |||
| constexpr bool is_schema_v = is_schema<T>::value; | |||
| template<typename T_schema, typename T_wrapped_dataset> | |||
| constexpr decltype(auto) operator()(T_schema&& schema, T_wrapped_dataset&& wrapped_dataset) const | |||
| { | |||
| using wrapped_datasets_type = mp::decay_t<decltype( | |||
| hana::transform( | |||
| std::declval<T_schema>().tables, | |||
| schema::table::get_wrapped_dataset))>; | |||
| using derived_wrapped_datasets_type = mp::decay_t<decltype( | |||
| hana::filter( | |||
| std::declval<wrapped_datasets_type>(), | |||
| hana::partial( | |||
| has_base, | |||
| std::declval<T_schema>(), | |||
| wrapped_dataset)))>; | |||
| return derived_wrapped_datasets_type { }; | |||
| } | |||
| }; | |||
| } | |||
| /** | |||
| * @brief Predicate to create an schema object from the passed attributes. | |||
| */ | |||
| constexpr decltype(auto) make_schema = mp::generic_predicate<__impl::schema_builder> { }; | |||
| constexpr decltype(auto) get_derived_types = __impl::schema_get_derived_types_impl { }; | |||
| } } | |||
| } | |||
| end_namespace_cpphibernate_schema | |||
| #include "schema.inl" | |||
| @@ -0,0 +1,102 @@ | |||
| #pragma once | |||
| #include "schema.h" | |||
| namespace cpphibernate { | |||
| namespace schema { | |||
| namespace __impl | |||
| { | |||
| /* tag_schema */ | |||
| struct tag_schema | |||
| { }; | |||
| /* schema_t */ | |||
| template<typename T_name, typename T_tables> | |||
| struct schema_t | |||
| : public tag_schema | |||
| , public tag_equality_comparable<tag_schema> | |||
| { | |||
| using name_type = T_name; | |||
| using tables_type = T_tables; | |||
| name_type name; | |||
| tables_type tables; | |||
| constexpr schema_t( | |||
| name_type&& p_name, | |||
| tables_type&& p_tables) | |||
| : name (std::forward<name_type> (p_name)) | |||
| , tables(std::forward<tables_type>(p_tables)) | |||
| { } | |||
| constexpr schema_t(schema_t&&) = default; | |||
| constexpr schema_t(const schema_t&) = delete; | |||
| constexpr schema_t& operator = (schema_t&&) = default; | |||
| constexpr schema_t& operator = (const schema_t&) = delete; | |||
| inline void print(std::ostream& os) const | |||
| { | |||
| using namespace ::cppcore; | |||
| size_t index = 0; | |||
| os << indent << '{' | |||
| << incindent | |||
| << indent << "\"name\": \"" << name << "\"," | |||
| << indent << "\"tables\": " | |||
| << indent << '[' | |||
| << incindent; | |||
| hana::for_each(tables, [&](auto& table){ | |||
| if (index++ > 0) os << ","; | |||
| table.print(os); | |||
| }); | |||
| os << decindent | |||
| << indent << ']' | |||
| << decindent | |||
| << indent << '}'; | |||
| } | |||
| }; | |||
| /* schema_builder */ | |||
| template<typename X, typename> | |||
| struct schema_builder | |||
| { | |||
| template<typename... T_args> | |||
| static constexpr decltype(auto) apply(T_args&&...) | |||
| { static_assert(sizeof...(T_args) == -1, "Invalid parameters for make_schema(...)!"); } | |||
| }; | |||
| template<typename T_name, typename T_tables> | |||
| struct schema_builder< | |||
| mp::list<T_name, T_tables>, | |||
| mp::enable_if_t< | |||
| is_tables_v<mp::decay_t<T_tables>>>> | |||
| { | |||
| using name_type = T_name; | |||
| using tables_type = T_tables; | |||
| using schema_type = schema_t<name_type, tables_type>; | |||
| static constexpr decltype(auto) apply( | |||
| name_type&& name, | |||
| tables_type&& tables) | |||
| { | |||
| return schema_type( | |||
| std::forward<name_type> (name), | |||
| std::forward<tables_type>(tables)); | |||
| } | |||
| }; | |||
| } | |||
| /* is_schema */ | |||
| template<typename T> | |||
| struct is_schema | |||
| : public mp::is_base_of<__impl::tag_schema, T> | |||
| { }; | |||
| } } | |||
| @@ -1,216 +0,0 @@ | |||
| #pragma once | |||
| #include <cpphibernate/config.h> | |||
| #include <cpphibernate/misc/general.h> | |||
| beg_namespace_cpphibernate_schema | |||
| { | |||
| namespace __impl | |||
| { | |||
| /* setter_t */ | |||
| template<typename T_dataset, typename T_value> | |||
| struct setter_t | |||
| { | |||
| using dataset_type = T_dataset; | |||
| using value_type = T_value; | |||
| }; | |||
| /* setter_none_t */ | |||
| struct setter_none_t | |||
| : public setter_t<void, void> | |||
| { | |||
| using base_type = setter_t<void, void>; | |||
| using dataset_type = typename base_type::dataset_type; | |||
| using value_type = typename base_type::value_type; | |||
| cpphibernate_constructable(setter_none_t, default); | |||
| cpphibernate_copyable (setter_none_t, delete); | |||
| cpphibernate_moveable (setter_none_t, default); | |||
| }; | |||
| /* setter_member_var_t */ | |||
| template<typename T_dataset, typename T_value, typename T_member> | |||
| struct setter_member_var_t | |||
| : public setter_t<T_dataset, T_value> | |||
| { | |||
| using base_type = setter_t<T_dataset, T_value>; | |||
| using value_type = typename base_type::value_type; | |||
| using dataset_type = typename base_type::dataset_type; | |||
| using member_type = T_member; | |||
| member_type member; | |||
| template<typename X_member> | |||
| constexpr setter_member_var_t(X_member&& p_member) | |||
| : member(std::forward<X_member>(p_member)) | |||
| { } | |||
| cpphibernate_copyable(setter_member_var_t, delete); | |||
| cpphibernate_moveable(setter_member_var_t, default); | |||
| template<typename X_dataset, typename X_value> | |||
| constexpr decltype(auto) operator()(X_dataset&& data, X_value&& value) const | |||
| { return std::forward<X_dataset>(data).*member = std::forward<X_value>(value); } | |||
| }; | |||
| /* setter_member_func_t */ | |||
| template<typename T_dataset, typename T_value, typename T_member> | |||
| struct setter_member_func_t | |||
| : public setter_t<T_dataset, T_value> | |||
| { | |||
| using base_type = setter_t<T_dataset, T_value>; | |||
| using value_type = typename base_type::value_type; | |||
| using dataset_type = typename base_type::dataset_type; | |||
| using member_type = T_member; | |||
| member_type member; | |||
| template<typename X_member> | |||
| constexpr setter_member_func_t(X_member&& p_member) | |||
| : member(std::forward<X_member>(p_member)) | |||
| { }; | |||
| cpphibernate_copyable(setter_member_func_t, delete); | |||
| cpphibernate_moveable(setter_member_func_t, default); | |||
| template<typename X_dataset, typename X_value> | |||
| constexpr decltype(auto) operator()(X_dataset&& data, X_value&& value) const | |||
| { return (std::forward<X_dataset>(data).*member)(std::forward<X_value>(value)); } | |||
| }; | |||
| /* setter_lambda_t */ | |||
| template<typename T_lambda, typename T_dataset, typename T_value> | |||
| struct setter_lambda_t | |||
| : public setter_t<T_dataset, T_value> | |||
| { | |||
| using base_type = setter_t<T_dataset, T_value>; | |||
| using value_type = typename base_type::value_type; | |||
| using dataset_type = typename base_type::dataset_type; | |||
| using lambda_type = T_lambda; | |||
| lambda_type lambda; | |||
| template<typename X_lambda> | |||
| constexpr setter_lambda_t(X_lambda&& p_lambda) | |||
| : lambda(std::forward<X_lambda>(p_lambda)) | |||
| { } | |||
| cpphibernate_copyable(setter_lambda_t, delete); | |||
| cpphibernate_moveable(setter_lambda_t, default); | |||
| template<typename X_dataset, typename X_value> | |||
| constexpr decltype(auto) operator()(X_dataset&& data, X_value&& value) const | |||
| { return lambda(std::forward<X_dataset>(data), std::forward<X_value>(value)); } | |||
| }; | |||
| /* is_setter_impl */ | |||
| template<typename T, typename = void> | |||
| struct is_setter_impl | |||
| : public mp::c_false_t | |||
| { }; | |||
| template<typename T> | |||
| struct is_setter_impl<T, mp::enable_if< | |||
| mp::is_base_of<setter_t<typename T::dataset_type, typename T::value_type>, T>>> | |||
| : public mp::c_true_t | |||
| { }; | |||
| } | |||
| /* meta */ | |||
| template<typename T> | |||
| struct is_setter : | |||
| public __impl::is_setter_impl<T> | |||
| { }; | |||
| /* make */ | |||
| constexpr decltype(auto) make_setter_none() | |||
| { | |||
| using setter_type = __impl::setter_none_t; | |||
| return setter_type(); | |||
| } | |||
| template<typename T_dataset, typename T_value> | |||
| constexpr decltype(auto) make_setter_member_var(T_value T_dataset::* member) | |||
| { | |||
| using setter_type = __impl::setter_member_var_t<T_dataset, T_value, T_value T_dataset::*>; | |||
| return setter_type(member); | |||
| } | |||
| template<typename T_dataset, typename T_value, typename T_return> | |||
| constexpr decltype(auto) make_setter_member_func(T_return (T_dataset::*member)(T_value)) | |||
| { | |||
| using setter_type = __impl::setter_member_func_t<T_dataset, T_value, T_return (T_dataset::*)(T_value)>; | |||
| return setter_type(member); | |||
| } | |||
| template<typename T_dataset, typename T_value, typename T_return> | |||
| constexpr decltype(auto) make_setter_member_func(T_return (T_dataset::*member)(T_value) const) | |||
| { | |||
| using setter_type = __impl::setter_member_func_t<const T_dataset, T_value, T_return (T_dataset::*)(T_value) const>; | |||
| return setter_type(member); | |||
| } | |||
| template<typename T_lambda, typename T_wrapped_dataset, typename T_wrapped_value> | |||
| constexpr decltype(auto) make_setter_lambda(T_lambda&& lambda, T_wrapped_dataset&&, T_wrapped_value&&) | |||
| { | |||
| using setter_type = __impl::setter_lambda_t<T_lambda, misc::decay_unwrap_t<T_wrapped_dataset>, misc::decay_unwrap_t<T_wrapped_value>>; | |||
| return setter_type(std::forward<T_lambda>(lambda)); | |||
| } | |||
| /* operations */ | |||
| namespace __impl | |||
| { | |||
| /* setter_make_impl */ | |||
| struct setter_make_impl | |||
| { | |||
| template<typename T_dataset, typename T_value> | |||
| constexpr decltype(auto) operator()(T_value T_dataset::*member) const | |||
| { return make_setter_member_var(member); } | |||
| template<typename T_dataset, typename T_value> | |||
| constexpr decltype(auto) operator()(void (T_dataset::*member)(T_value)) const | |||
| { return make_setter_member_func(member); } | |||
| template<typename T_dataset, typename T_value> | |||
| constexpr decltype(auto) operator()(void (T_dataset::*member)(T_value&)) const | |||
| { return make_setter_member_func(member); } | |||
| template<typename T_dataset, typename T_value> | |||
| constexpr decltype(auto) operator()(void (T_dataset::*member)(T_value&&)) const | |||
| { return make_setter_member_func(member); } | |||
| template<typename T_func, typename T_wrapped_dataset, typename T_wrapped_value> | |||
| constexpr decltype(auto) operator()(T_func&& func, T_wrapped_dataset&&, T_wrapped_value&&) const | |||
| { return make_setter_lambda(std::forward<T_func>(func), T_wrapped_dataset { }, T_wrapped_value { }); } | |||
| template<typename T_setter> | |||
| constexpr auto operator()(T_setter&& setter) const | |||
| -> mp::enable_if<is_setter<T_setter>, T_setter> | |||
| { return std::forward<T_setter>(setter); } | |||
| }; | |||
| } | |||
| namespace setter | |||
| { | |||
| constexpr decltype(auto) make = __impl::setter_make_impl { }; | |||
| } | |||
| } | |||
| end_namespace_cpphibernate_schema | |||
| @@ -1,190 +1,38 @@ | |||
| #pragma once | |||
| #include <cpphibernate/config.h> | |||
| #include <cpphibernate/misc/wrap.h> | |||
| #include <cpphibernate/misc/general.h> | |||
| #include <cpphibernate/schema/fields.h> | |||
| #include <cpphibernate/schema/attribute.h> | |||
| beg_namespace_cpphibernate_schema | |||
| { | |||
| namespace cpphibernate { | |||
| namespace schema { | |||
| namespace __impl | |||
| { | |||
| /* table_t */ | |||
| template<typename T_name, typename T_wrapped_dataset, typename T_table_id, typename T_fields> | |||
| struct table_t | |||
| { | |||
| using name_type = T_name; | |||
| using wrapped_dataset_type = mp::decay_t<T_wrapped_dataset>; | |||
| using dataset_type = misc::decay_unwrap_t<wrapped_dataset_type>; | |||
| using table_id_type = T_table_id; | |||
| using fields_type = T_fields; | |||
| using this_type = table_t<name_type, wrapped_dataset_type, table_id_type, fields_type>; | |||
| name_type name; | |||
| wrapped_dataset_type wrapped_dataset; | |||
| table_id_type table_id; | |||
| fields_type fields; | |||
| constexpr table_t( | |||
| T_name p_name, | |||
| T_wrapped_dataset p_wrapped_dataset, | |||
| T_table_id p_table_id, | |||
| T_fields p_fields) | |||
| : name (std::forward<T_name> (p_name)) | |||
| , wrapped_dataset (std::forward<T_wrapped_dataset>(p_wrapped_dataset)) | |||
| , table_id (std::forward<T_table_id> (p_table_id)) | |||
| , fields (std::forward<T_fields> (p_fields)) | |||
| { } | |||
| cpphibernate_copyable(table_t, delete); | |||
| cpphibernate_moveable(table_t, default); | |||
| cpphibernate_equality_comparable(); | |||
| inline void print(std::ostream& os) const | |||
| { | |||
| using namespace ::utl; | |||
| size_t index = 0; | |||
| os << indent << '{' | |||
| << incindent | |||
| << indent << "\"name\": \"" << name << "\"," | |||
| << indent << "\"wrapped_dataset\": \"" << utl::type_helper<misc::decay_unwrap_t<wrapped_dataset_type>>::name() << "\"" | |||
| << indent << "\"table_id\": \"" << hana::value(table_id) << "\"" | |||
| << indent << "\"fields\": " | |||
| << indent << '[' | |||
| << incindent; | |||
| hana::for_each(fields, [&](auto& field){ | |||
| if (index++ > 0) os << ","; | |||
| field.print(os); | |||
| }); | |||
| os << decindent | |||
| << indent << ']' | |||
| << decindent | |||
| << indent << '}'; | |||
| } | |||
| }; | |||
| } | |||
| /* meta */ | |||
| template<typename T> | |||
| struct is_table | |||
| : public mp::is_specialization_of<T, __impl::table_t> | |||
| { }; | |||
| template<typename... T> | |||
| struct all_are_tables | |||
| : mp::all_true<is_table<T>::value...> | |||
| { }; | |||
| /* operations */ | |||
| namespace __impl | |||
| { | |||
| /* table_make_impl */ | |||
| template <typename X, typename = void> | |||
| struct table_make_impl | |||
| { | |||
| template <typename... T_args> | |||
| static constexpr decltype(auto) apply(T_args&&... args) | |||
| { static_assert(sizeof...(args) == -1, "Invalid parameters for hibernate::schema::table::make(...)!"); } | |||
| }; | |||
| template<typename T_name, typename T_wrapped_dataset, typename T_id, typename T_fields> | |||
| struct table_make_impl<mp::list<T_name, T_wrapped_dataset, T_id, T_fields>, mp::enable_if_c< | |||
| hana::is_a<hana::type_tag, T_wrapped_dataset> | |||
| && is_fields<mp::decay_t<T_fields>>::value>> | |||
| { | |||
| static constexpr decltype(auto) apply(T_name&& name, T_wrapped_dataset&& wrapped_dataset, T_id&& id, T_fields&& fields) | |||
| { | |||
| return table_t<T_name, T_wrapped_dataset, T_id, T_fields>( | |||
| std::forward<T_name> (name), | |||
| std::forward<T_wrapped_dataset> (wrapped_dataset), | |||
| std::forward<T_id> (id), | |||
| std::forward<T_fields> (fields)); | |||
| } | |||
| }; | |||
| /* table_get_wrapped_dataset_impl */ | |||
| struct table_get_wrapped_dataset_impl | |||
| { | |||
| template<typename T_table> | |||
| constexpr decltype(auto) operator()(T_table&& table) const | |||
| { return table.wrapped_dataset; } | |||
| }; | |||
| /* table_get_primary_key_field_impl */ | |||
| /** | |||
| * @brief Helper type to build table objects. | |||
| */ | |||
| template<typename X, typename = void> | |||
| struct table_get_primary_key_field_impl | |||
| { | |||
| template <typename... T_args> | |||
| static constexpr decltype(auto) apply(T_args&&... args) | |||
| { static_assert(sizeof...(args) == -1, "Invalid parameters for hibernate::schema::table::get_primary_key_field(...)!"); } | |||
| }; | |||
| template<typename T_table> | |||
| struct table_get_primary_key_field_impl< | |||
| mp::list<T_table>, | |||
| mp::enable_if_c< | |||
| is_table<mp::decay_t<T_table>>::value>> | |||
| { | |||
| template<size_t I> | |||
| using is_primary_key_field = decltype(hana::contains( | |||
| std::declval<T_table>().fields[hana::size_c<I>].attributes, | |||
| attribute::primary_key)); | |||
| template<size_t I, size_t N, typename = void> | |||
| struct helper; | |||
| template<size_t N> | |||
| struct helper<N, N, void> | |||
| { static_assert(N != N, "Unable to find primary key field for table!"); }; | |||
| template<size_t I, size_t N> | |||
| struct helper<I, N, mp::enable_if_c< | |||
| !is_primary_key_field<I>::value>> | |||
| { | |||
| static constexpr decltype(auto) apply(T_table&& table) | |||
| { return helper<I+1, N>::apply(std::forward<T_table>(table)); } | |||
| }; | |||
| template<size_t I, size_t N> | |||
| struct helper<I, N, mp::enable_if_c< | |||
| is_primary_key_field<I>::value>> | |||
| { | |||
| static constexpr decltype(auto) apply(T_table&& table) | |||
| { return std::forward<T_table>(table).fields[hana::size_c<I>]; } | |||
| }; | |||
| static constexpr decltype(auto) apply(T_table&& table) | |||
| { | |||
| using count = mp::decay_t<decltype(hana::size(std::declval<T_table>().fields))>; | |||
| return helper<0, count::value>::apply( | |||
| std::forward<T_table>(table)); | |||
| } | |||
| }; | |||
| struct table_builder; | |||
| } | |||
| namespace table | |||
| { | |||
| constexpr decltype(auto) make = misc::make_generic_predicate<__impl::table_make_impl> { }; | |||
| /** | |||
| * @brief Evaluates to true_t if the passed type is a table type. | |||
| */ | |||
| template<typename T> | |||
| struct is_table; | |||
| constexpr decltype(auto) get_wrapped_dataset = __impl::table_get_wrapped_dataset_impl { }; | |||
| /** | |||
| * @brief Is true if the passed type is an attributes type, false otherwise. | |||
| */ | |||
| template<typename T> | |||
| constexpr bool is_table_v = is_table<T>::value; | |||
| constexpr decltype(auto) get_primary_key_field = misc::make_generic_predicate<__impl::table_get_primary_key_field_impl> { }; | |||
| /** | |||
| * @brief Predicate to create an table object from the passed attributes. | |||
| */ | |||
| constexpr decltype(auto) make_table = mp::generic_predicate<__impl::table_builder> { }; | |||
| } | |||
| } } | |||
| } | |||
| end_namespace_cpphibernate_schema | |||
| #include "table.inl" | |||
| @@ -0,0 +1,129 @@ | |||
| #pragma once | |||
| #include "table.h" | |||
| namespace cpphibernate { | |||
| namespace schema { | |||
| namespace __impl | |||
| { | |||
| /* tag_table */ | |||
| struct tag_table | |||
| { }; | |||
| /* table_t */ | |||
| template< | |||
| typename T_name, | |||
| typename T_wrapped_dataset, | |||
| typename T_table_id, | |||
| typename T_fields> | |||
| struct table_t | |||
| : public tag_table | |||
| , public tag_equality_comparable<tag_table> | |||
| { | |||
| using name_type = T_name; | |||
| using wrapped_dataset_type = mp::decay_t<T_wrapped_dataset>; | |||
| using dataset_type = decay_unwrap_t<wrapped_dataset_type>; | |||
| using table_id_type = T_table_id; | |||
| using fields_type = T_fields; | |||
| using this_type = table_t<name_type, wrapped_dataset_type, table_id_type, fields_type>; | |||
| name_type name; | |||
| wrapped_dataset_type wrapped_dataset; | |||
| table_id_type table_id; | |||
| fields_type fields; | |||
| constexpr table_t( | |||
| name_type p_name, | |||
| wrapped_dataset_type p_wrapped_dataset, | |||
| table_id_type p_table_id, | |||
| fields_type p_fields) | |||
| : name (std::forward<name_type> (p_name)) | |||
| , wrapped_dataset (std::forward<wrapped_dataset_type>(p_wrapped_dataset)) | |||
| , table_id (std::forward<table_id_type> (p_table_id)) | |||
| , fields (std::forward<fields_type> (p_fields)) | |||
| { } | |||
| constexpr table_t(table_t&&) = default; | |||
| constexpr table_t(const table_t&) = delete; | |||
| constexpr table_t& operator = (table_t&&) = default; | |||
| constexpr table_t& operator = (const table_t&) = delete; | |||
| inline void print(std::ostream& os) const | |||
| { | |||
| using namespace ::cppcore; | |||
| size_t index = 0; | |||
| os << indent << '{' | |||
| << incindent | |||
| << indent << "\"name\": \"" << name << "\"," | |||
| << indent << "\"wrapped_dataset\": \"" << type_helper<dataset_type>::name() << "\"" | |||
| << indent << "\"table_id\": \"" << hana::value(table_id) << "\"" | |||
| << indent << "\"fields\": " | |||
| << indent << '[' | |||
| << incindent; | |||
| hana::for_each(fields, [&](auto& table){ | |||
| if (index++ > 0) os << ","; | |||
| table.print(os); | |||
| }); | |||
| os << decindent | |||
| << indent << ']' | |||
| << decindent | |||
| << indent << '}'; | |||
| } | |||
| }; | |||
| /* table_builder */ | |||
| template<typename X, typename> | |||
| struct table_builder | |||
| { | |||
| template<typename... T_args> | |||
| static constexpr decltype(auto) apply(T_args&&...) | |||
| { static_assert(sizeof...(T_args) == -1, "Invalid parameters for make_table(...)!"); } | |||
| }; | |||
| template< | |||
| typename T_name, | |||
| typename T_wrapped_dataset, | |||
| typename T_table_id, | |||
| typename T_fields> | |||
| struct table_builder< | |||
| mp::list<T_name, T_wrapped_dataset, T_table_id, T_fields>, | |||
| mp::enable_if_t< | |||
| mp::is_valid_v<unwrap_t<mp::decay_t<T_wrapped_dataset>>> | |||
| && is_fields_v<mp::decay_t<T_fields>>>> | |||
| { | |||
| using name_type = T_name; | |||
| using wrapped_dataset_type = T_wrapped_dataset; | |||
| using table_id_type = T_table_id; | |||
| using fields_type = T_fields; | |||
| using table_type = table_t<name_type, wrapped_dataset_type, table_id_type, fields_type>; | |||
| static constexpr decltype(auto) apply( | |||
| name_type&& name, | |||
| wrapped_dataset_type&& wrapped_dataset, | |||
| table_id_type&& table_id, | |||
| fields_type&& fields) | |||
| { | |||
| return table_type( | |||
| std::forward<name_type> (name), | |||
| std::forward<wrapped_dataset_type> (wrapped_dataset), | |||
| std::forward<table_id_type> (table_id), | |||
| std::forward<fields_type> (fields)); | |||
| } | |||
| }; | |||
| } | |||
| /* is_table */ | |||
| template<typename T> | |||
| struct is_table | |||
| : public mp::is_specialization_of<T, __impl::table_t> | |||
| { }; | |||
| } } | |||
| @@ -1,120 +1,39 @@ | |||
| #pragma once | |||
| #include <cpphibernate/config.h> | |||
| #include <cpphibernate/misc/general.h> | |||
| #include <cpphibernate/schema/table.h> | |||
| beg_namespace_cpphibernate_schema | |||
| { | |||
| namespace cpphibernate { | |||
| namespace schema { | |||
| namespace __impl | |||
| { | |||
| /* tables_t */ | |||
| template<typename... T_table> | |||
| using tables_t = hana::tuple<T_table...>; | |||
| /* is_tables_impl */ | |||
| /** | |||
| * @brief Helper type to build tables. | |||
| */ | |||
| template<typename T, typename = void> | |||
| struct is_tables_impl | |||
| : mp::c_false_t | |||
| { }; | |||
| template<typename... T> | |||
| struct is_tables_impl<tables_t<T...>, mp::enable_if<all_are_tables<T...>>> | |||
| : mp::c_true_t | |||
| { }; | |||
| struct tables_builder; | |||
| } | |||
| /* meta */ | |||
| /** | |||
| * @brief Evaluates to true_t if the passed type is a tables type. | |||
| */ | |||
| template<typename T> | |||
| struct is_tables | |||
| : public __impl::is_tables_impl<T> | |||
| { }; | |||
| /* operations */ | |||
| namespace __impl | |||
| { | |||
| /* tables_make_impl */ | |||
| template <typename X, typename = void> | |||
| struct tables_make_impl | |||
| { | |||
| template <typename... T_args> | |||
| static constexpr decltype(auto) apply(T_args&&... args) | |||
| { static_assert(sizeof...(args) == -1, "Invalid parameters for hibernate::schema::tables::make(...)!"); } | |||
| }; | |||
| template<typename... T> | |||
| struct tables_make_impl<mp::list<T...>, mp::enable_if<all_are_tables<T...>>> | |||
| { | |||
| template <typename ...T_tables> | |||
| static constexpr decltype(auto) apply(T_tables&&... tables) | |||
| { return tables_t<T_tables...>(std::forward<T_tables>(tables)...); } | |||
| }; | |||
| /* tables_find_impl */ | |||
| struct is_tables; | |||
| template<typename X, typename = void> | |||
| struct tables_find_impl | |||
| { | |||
| template<typename... T_args> | |||
| static constexpr decltype(auto) apply(T_args&&... args) | |||
| { static_assert(sizeof...(args) == -1, "Invalid parameters for hibernate::schema::tables::find(...)!"); } | |||
| }; | |||
| template<typename T_tables, typename T_wrapped_dataset> | |||
| struct tables_find_impl< | |||
| mp::list<T_tables, T_wrapped_dataset>, | |||
| mp::enable_if_c< | |||
| is_tables<mp::decay_t<T_tables>>::value>> | |||
| { | |||
| template<size_t I, size_t N, typename = void> | |||
| struct helper; | |||
| template<size_t N> | |||
| struct helper<N, N, void> | |||
| { static_assert(N != N, "Table for given datatype does not exist!"); }; | |||
| template<size_t I, size_t N> | |||
| struct helper<I, N, mp::enable_if_c< | |||
| decltype(hana::not_equal(std::declval<T_tables>()[hana::size_c<I>].wrapped_dataset, T_wrapped_dataset { }))::value>> | |||
| { | |||
| static constexpr decltype(auto) apply(T_tables&& tables) | |||
| { return helper<I+1, N>::apply(std::forward<T_tables>(tables)); } | |||
| }; | |||
| template<size_t I, size_t N> | |||
| struct helper<I, N, mp::enable_if_c< | |||
| decltype(hana::equal(std::declval<T_tables>()[hana::size_c<I>].wrapped_dataset, T_wrapped_dataset { }))::value>> | |||
| { | |||
| static constexpr decltype(auto) apply(T_tables&& tables) | |||
| { return std::forward<T_tables>(tables)[hana::size_c<I>]; } | |||
| }; | |||
| static constexpr decltype(auto) apply(T_tables&& tables, T_wrapped_dataset&&) | |||
| { | |||
| using count_type = mp::decay_t<decltype(hana::size(std::declval<T_tables>()))>; | |||
| return helper<0, count_type::value>::apply(std::forward<T_tables>(tables)); | |||
| } | |||
| }; | |||
| } | |||
| namespace tables | |||
| { | |||
| constexpr decltype(auto) make = misc::make_generic_predicate<__impl::tables_make_impl> { }; | |||
| /** | |||
| * @brief Is true if the passed type is an tables type, false otherwise. | |||
| */ | |||
| template<typename T> | |||
| constexpr bool is_tables_v = is_tables<T>::value; | |||
| constexpr decltype(auto) find = misc::make_generic_predicate<__impl::tables_find_impl> { }; | |||
| /** | |||
| * @brief Predicate to create an tables object from the passed tables. | |||
| */ | |||
| constexpr decltype(auto) make_tables = mp::generic_predicate<__impl::tables_builder> { }; | |||
| } | |||
| } } | |||
| } | |||
| end_namespace_cpphibernate_schema | |||
| #include "tables.inl" | |||
| @@ -0,0 +1,63 @@ | |||
| #pragma once | |||
| #include "tables.h" | |||
| namespace cpphibernate { | |||
| namespace schema { | |||
| namespace __impl | |||
| { | |||
| /* tables_t */ | |||
| template<typename... T_tables> | |||
| using tables_t = hana::basic_tuple<T_tables...>; | |||
| /* tables_builder */ | |||
| template<typename T, typename> | |||
| struct tables_builder | |||
| { | |||
| template<typename... T_args> | |||
| static constexpr decltype(auto) apply(T_args&&...) | |||
| { static_assert(sizeof...(T_args) == -1, "Invalid parameters for make_tables(...)!"); } | |||
| }; | |||
| template<typename... T> | |||
| struct tables_builder< | |||
| mp::list<T...>, | |||
| mp::enable_if_t<mp::is_true_v< | |||
| is_table_v<mp::decay_t<T>>...>>> | |||
| { | |||
| template<typename... T_args> | |||
| static constexpr decltype(auto) apply(T_args&&... args) | |||
| { | |||
| using tables_type = tables_t<T_args...>; | |||
| return tables_type(std::forward<T_args>(args)...); | |||
| } | |||
| }; | |||
| /* is_tables_impl */ | |||
| template<typename T, typename = void> | |||
| struct is_tables_impl | |||
| : mp::false_t | |||
| { }; | |||
| template<typename... T> | |||
| struct is_tables_impl< | |||
| tables_t<T...>, | |||
| mp::enable_if_t<mp::is_true_v<is_table_v<mp::decay_t<T>>...>>> | |||
| : mp::true_t | |||
| { }; | |||
| } | |||
| /* is_tables */ | |||
| template<typename T> | |||
| struct is_tables | |||
| : public __impl::is_tables_impl<T> | |||
| { }; | |||
| } } | |||
| @@ -1,75 +1,114 @@ | |||
| #pragma once | |||
| #include <string> | |||
| #include <cstddef> | |||
| #include <iostream> | |||
| #include <cpphibernate/config.h> | |||
| #include <cpputils/misc/exception.h> | |||
| beg_namespace_cpphibernate | |||
| namespace cpphibernate | |||
| { | |||
| /* string */ | |||
| /** | |||
| * @brief Represents a string with an fixed length. | |||
| */ | |||
| template<size_t N> | |||
| struct string | |||
| : public std::string | |||
| { | |||
| static constexpr decltype(auto) max_size = N; | |||
| using std::string::string; | |||
| using std::string::operator=; | |||
| }; | |||
| /* timestamp */ | |||
| /** | |||
| * @brief Timestamp class. | |||
| */ | |||
| struct timestamp | |||
| { | |||
| uint64_t value; | |||
| /** | |||
| * @brief Default constructor. | |||
| */ | |||
| inline timestamp() = default; | |||
| inline timestamp(uint64_t v) | |||
| : value(v) | |||
| { } | |||
| /** | |||
| * @brief Value constructor. | |||
| */ | |||
| inline timestamp(uint64_t v); | |||
| inline timestamp& operator=(const uint64_t& v) | |||
| { | |||
| value = v; | |||
| return *this; | |||
| } | |||
| /** | |||
| * @brief Value assignment constructor. | |||
| */ | |||
| inline timestamp& operator=(const uint64_t& v); | |||
| inline operator uint64_t() const | |||
| { return value; } | |||
| /** | |||
| * @brief Impicit type conversion to base type. | |||
| */ | |||
| inline operator uint64_t() const; | |||
| }; | |||
| /* uuid */ | |||
| /** | |||
| * @brief A typical UUID implementation. | |||
| */ | |||
| struct uuid | |||
| : public std::array<uint8_t, 16> | |||
| { | |||
| public: | |||
| inline uuid() | |||
| : std::array<uint8_t, 16>::array({ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }) | |||
| { } | |||
| inline uuid(const std::string& str) | |||
| : std::array<uint8_t, 16>::array({ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }) | |||
| { | |||
| if (!from_string(str, *this)) | |||
| throw utl::argument_exception("str", "invalid uuid"); | |||
| } | |||
| cpphibernate_copyable(uuid, default); | |||
| cpphibernate_moveable(uuid, default); | |||
| /** | |||
| * @brief Default constructor. | |||
| */ | |||
| inline uuid(); | |||
| /** | |||
| * @brief Construtor to create a UUID from a string. | |||
| * | |||
| * @param[in] str String to create UUID from. | |||
| */ | |||
| inline uuid(const std::string& str); | |||
| /** | |||
| * @brief Move constructor. | |||
| */ | |||
| inline uuid(uuid&&) = default; | |||
| /** | |||
| * @brief Copy constructor. | |||
| */ | |||
| inline uuid(const uuid&) = default; | |||
| /** | |||
| * @brief Write the UUID to passed stream. | |||
| * | |||
| * @param[in] os Stream to write UUID to. | |||
| */ | |||
| void to_string(std::ostream& os) const; | |||
| /** | |||
| * @brief Write the UUID to passed stream. | |||
| * | |||
| * @param[in] os Stream to write UUID to. | |||
| * | |||
| * @return Stream passed as parameter. | |||
| */ | |||
| std::ostream& operator<<(std::ostream& os) const; | |||
| public: | |||
| /** | |||
| * @brief Create an UUID object from an string. | |||
| * | |||
| * @param[in] str String to create UUID from. | |||
| * @param[in] val Parameter to store converted object in | |||
| * | |||
| * @retval true If the convertion was successful. | |||
| * @retval false If the string could not be converted. | |||
| */ | |||
| static bool from_string(const std::string& str, uuid& val); | |||
| }; | |||
| } | |||
| end_namespace_cpphibernate | |||
| #include "types.inl" | |||
| @@ -0,0 +1,38 @@ | |||
| #pragma once | |||
| #include <cppcore/misc/exception.h> | |||
| #include "types.h" | |||
| namespace cpphibernate | |||
| { | |||
| /* timestamp */ | |||
| timestamp::timestamp(uint64_t v) | |||
| : value(v) | |||
| { } | |||
| timestamp& timestamp::operator=(const uint64_t& v) | |||
| { | |||
| value = v; | |||
| return *this; | |||
| } | |||
| timestamp::operator uint64_t() const | |||
| { return value; } | |||
| /* uuid */ | |||
| uuid::uuid() | |||
| : std::array<uint8_t, 16>::array({ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }) | |||
| { } | |||
| uuid::uuid(const std::string& str) | |||
| : std::array<uint8_t, 16>::array({ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }) | |||
| { | |||
| if (!from_string(str, *this)) | |||
| throw ::cppcore::argument_exception("str", "invalid uuid"); | |||
| } | |||
| } | |||
| @@ -1,53 +1,105 @@ | |||
| # Initialize ###################################################################################### | |||
| Include ( cotire OPTIONAL ) | |||
| Include ( pedantic OPTIONAL ) | |||
| Include ( strip_symbols OPTIONAL ) | |||
| Include ( cotire OPTIONAL RESULT_VARIABLE HAS_COTIRE ) | |||
| Include ( pedantic OPTIONAL RESULT_VARIABLE HAS_PEDANTIC ) | |||
| Include ( strip_symbols OPTIONAL RESULT_VARIABLE HAS_STRIP_SYMBOLS ) | |||
| Include ( ${CMAKE_CURRENT_SOURCE_DIR}/../cmake/options.cmake ) | |||
| Find_Package ( Hana REQUIRED ) | |||
| Find_Package ( cppmp REQUIRED ) | |||
| Find_Package ( cppcore REQUIRED ) | |||
| Set ( BUILD_SHARED_LIBS ${CPPHIBERNATE_BUILD_SHARED} ) | |||
| Set ( CMAKE_CXX_STANDARD 17 ) | |||
| Set ( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${PEDANTIC_C_FLAGS}" ) | |||
| Set ( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${PEDANTIC_CXX_FLAGS}" ) | |||
| # Object Library ################################################################################## | |||
| # Dependencies #################################################################################### | |||
| Set ( CMAKE_POSITION_INDEPENDENT_CODE ON ) | |||
| Set ( CPPHIBERNATE_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../include ) | |||
| File ( GLOB_RECURSE CPPHIBERNATE_HEADER_FILES ${CPPHIBERNATE_INCLUDE_DIR}/*.h ) | |||
| File ( GLOB_RECURSE CPPHIBERNATE_INLINE_FILES ${CPPHIBERNATE_INCLUDE_DIR}/*.inl ) | |||
| File ( GLOB_RECURSE CPPHIBERNATE_SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp ) | |||
| Add_Library ( cpphibernate-objects | |||
| OBJECT | |||
| ${CPPHIBERNATE_HEADER_FILES} | |||
| ${CPPHIBERNATE_INLINE_FILES} | |||
| ${CPPHIBERNATE_SOURCE_FILES} ) | |||
| Target_Include_Directories ( cpphibernate-objects | |||
| PUBLIC | |||
| $<BUILD_INTERFACE:${CPPHIBERNATE_INCLUDE_DIR}> | |||
| $<INSTALL_INTERFACE:${CPPHIBERNATE_INSTALL_DIR_INCLUDE}> ) | |||
| Target_Link_Libraries ( cpphibernate-objects | |||
| PUBLIC | |||
| hana | |||
| cppmp::cppmp | |||
| cppcore::cppcore ) | |||
| Find_Package ( cpputils REQUIRED ) | |||
| Find_Package ( cppmariadb REQUIRED ) | |||
| # Static Library ################################################################################## | |||
| # Project: cpphibernate ############################################################################### | |||
| Add_Library ( cpphibernate-static STATIC $<TARGET_OBJECTS:cpphibernate-objects> ) | |||
| Set_Target_Properties ( cpphibernate-static | |||
| PROPERTIES | |||
| OUTPUT_NAME "${CPPHIBERNATE_OUTPUTNAME}" | |||
| VERSION ${CPPHIBERNATE_VERSION} ) | |||
| Target_Include_Directories ( cpphibernate-static | |||
| PUBLIC | |||
| $<BUILD_INTERFACE:${CPPHIBERNATE_INCLUDE_DIR}> | |||
| $<INSTALL_INTERFACE:${CPPHIBERNATE_INSTALL_DIR_INCLUDE}> ) | |||
| # Build | |||
| Project ( cpphibernate VERSION 1.0.0.0 LANGUAGES CXX ) | |||
| Set ( CPPHIBERNATE_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../include ) | |||
| Set ( CPPHIBERNATE_GENERATE_DIR ${CMAKE_CURRENT_BINARY_DIR}/generated ) | |||
| File ( GLOB_RECURSE SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp ) | |||
| Add_Library ( cpphibernate ${SOURCE_FILES} ) | |||
| Configure_File ( ${CMAKE_CURRENT_SOURCE_DIR}/../cmake/options.h.in | |||
| ${CPPHIBERNATE_GENERATE_DIR}/cpphibernate/options.h ) | |||
| Target_Include_Directories ( cpphibernate | |||
| PUBLIC ${CPPHIBERNATE_INCLUDE_DIR} | |||
| ${CPPHIBERNATE_GENERATE_DIR} ) | |||
| Target_Link_Libraries ( cpphibernate | |||
| cpputils | |||
| cppmariadb ) | |||
| # Install | |||
| If ( BUILD_SHARED_LIBS OR CPPHIBERNATE_INSTALL_DEV_FILES ) | |||
| Install ( TARGETS cpphibernate DESTINATION lib ) | |||
| # Shared Library ################################################################################## | |||
| Add_Library ( cpphibernate-shared SHARED $<TARGET_OBJECTS:cpphibernate-objects> ) | |||
| Set_Target_Properties ( cpphibernate-shared | |||
| PROPERTIES | |||
| OUTPUT_NAME "${CPPHIBERNATE_OUTPUTNAME}" | |||
| VERSION ${CPPHIBERNATE_VERSION} | |||
| SOVERSION ${CPPHIBERNATE_VERSION_SHORT} ) | |||
| Target_Include_Directories ( cpphibernate-shared | |||
| PUBLIC | |||
| $<BUILD_INTERFACE:${CPPHIBERNATE_INCLUDE_DIR}> | |||
| $<INSTALL_INTERFACE:${CPPHIBERNATE_INSTALL_DIR_INCLUDE}> ) | |||
| # Optimization #################################################################################### | |||
| # pedantic | |||
| If ( HAS_PEDANTIC ) | |||
| Pedantic_Apply_Flags_Target ( cpphibernate-objects ALL ) | |||
| Pedantic_Apply_Flags_Target ( cpphibernate-static ALL ) | |||
| Pedantic_Apply_Flags_Target ( cpphibernate-shared ALL ) | |||
| EndIf ( ) | |||
| # cotire | |||
| If ( HAS_COTIRE ) | |||
| Cotire ( cpphibernate-objects ) | |||
| Cotire ( cpphibernate-static ) | |||
| Cotire ( cpphibernate-shared ) | |||
| EndIf ( ) | |||
| # Install ######################################################################################### | |||
| # Header | |||
| If ( CPPHIBERNATE_INSTALL_HEADER ) | |||
| Install ( FILES ${CPPHIBERNATE_INCLUDE_DIR}/cpphibernate.h | |||
| DESTINATION ${CPPHIBERNATE_INSTALL_DIR_INCLUDE} ) | |||
| Install ( DIRECTORY ${CPPHIBERNATE_INCLUDE_DIR}/cpphibernate | |||
| DESTINATION ${CPPHIBERNATE_INSTALL_DIR_INCLUDE} ) | |||
| EndIf ( ) | |||
| # Static | |||
| If ( CPPHIBERNATE_INSTALL_STATIC ) | |||
| Install ( TARGETS cpphibernate-static | |||
| EXPORT cpphibernate | |||
| DESTINATION ${CPPHIBERNATE_INSTALL_DIR_LIB} ) | |||
| EndIf ( ) | |||
| If ( CPPHIBERNATE_INSTALL_DEV_FILES ) | |||
| Install ( FILES ${CPPHIBERNATE_INCLUDE_DIR}/cpphibernate.h DESTINATION include ) | |||
| Install ( DIRECTORY ${CPPHIBERNATE_INCLUDE_DIR}/cpphibernate DESTINATION include ) | |||
| Install ( DIRECTORY ${CPPHIBERNATE_GENERATE_DIR}/cpphibernate DESTINATION include ) | |||
| # Shared | |||
| If ( CPPHIBERNATE_INSTALL_SHARED ) | |||
| Install ( TARGETS cpphibernate-shared | |||
| EXPORT cpphibernate | |||
| DESTINATION ${CPPHIBERNATE_INSTALL_DIR_LIB} ) | |||
| EndIf ( ) | |||
| # Optimize | |||
| If ( __COTIRE_INCLUDED ) | |||
| Cotire ( cpphibernate ) | |||
| # Debug | |||
| If ( HAS_STRIP_SYMBOLS AND NOT CPPHIBERNATE_NO_STRIP ) | |||
| Strip_Symbols ( cpphibernate-shared CPPHIBERNATE_DBG_FILE ) | |||
| If ( CPPHIBERNATE_INSTALL_DEBUG ) | |||
| Install ( FILES ${CPPHIBERNATE_DBG_FILE} | |||
| DESTINATION ${CPPHIBERNATE_INSTALL_DIR_LIB} ) | |||
| EndIf ( ) | |||
| EndIf ( ) | |||
| If ( __STRIP_SYMBOLS_INCLUDED AND BUILD_SHARED_LIBS ) | |||
| Strip_Symbols ( cpphibernate DBG_FILE ) | |||
| EndIf () | |||
| @@ -1,31 +1,43 @@ | |||
| # Initialize ###################################################################################### | |||
| Include ( cotire OPTIONAL ) | |||
| Include ( pedantic OPTIONAL ) | |||
| Include ( cmake_tests OPTIONAL ) | |||
| Include ( ${CMAKE_CURRENT_SOURCE_DIR}/../cmake/options.cmake ) | |||
| Set ( CMAKE_CXX_STANDARD 17 ) | |||
| Set ( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${PEDANTIC_C_FLAGS}" ) | |||
| Set ( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${PEDANTIC_CXX_FLAGS}" ) | |||
| # Project: test_cpphibernate ########################################################################## | |||
| Project ( test_cpphibernate ) | |||
| File ( GLOB_RECURSE SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp ) | |||
| List ( FILTER SOURCE_FILES EXCLUDE REGEX "/_[A-Za-z0-9_-]*\.cpp$" ) | |||
| Add_Executable ( test_cpphibernate EXCLUDE_FROM_ALL ${SOURCE_FILES} ) | |||
| Target_Link_Libraries ( test_cpphibernate | |||
| cpphibernate | |||
| gmock_main | |||
| gmock | |||
| gtest | |||
| pthread ) | |||
| If ( __COTIRE_INCLUDED ) | |||
| Cotire ( test_cpphibernate ) | |||
| Include ( cotire OPTIONAL RESULT_VARIABLE HAS_COTIRE ) | |||
| Include ( pedantic OPTIONAL RESULT_VARIABLE HAS_PEDANTIC ) | |||
| Include ( cmake_tests OPTIONAL RESULT_VARIABLE HAS_CMAKE_TESTS ) | |||
| # Test ############################################################################################ | |||
| Find_Package ( GTest ) | |||
| If ( NOT "${GTest_FOUND}" ) | |||
| Return ( ) | |||
| EndIf ( ) | |||
| If ( __CMAKE_TESTS_INCLUDED ) | |||
| Add_CMake_Test ( NAME cpphibernate | |||
| TARGET test_cpphibernate ) | |||
| File ( GLOB_RECURSE CPPHIBERNATE_TEST_HEADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/*.h ) | |||
| File ( GLOB_RECURSE CPPHIBERNATE_TEST_INLINE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/*.inl ) | |||
| File ( GLOB_RECURSE CPPHIBERNATE_TEST_SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp ) | |||
| Add_Executable ( cpphibernate-test | |||
| EXCLUDE_FROM_ALL | |||
| ${CPPHIBERNATE_TEST_HEADER_FILES} | |||
| ${CPPHIBERNATE_TEST_INLINE_FILES} | |||
| ${CPPHIBERNATE_TEST_SOURCE_FILES} ) | |||
| Target_Link_Libraries ( cpphibernate-test | |||
| PUBLIC | |||
| cpphibernate-objects | |||
| GTest::Main ) | |||
| # pedantic | |||
| If ( HAS_PEDANTIC ) | |||
| Pedantic_Apply_Flags_Target ( cpphibernate-test ALL ) | |||
| EndIf ( ) | |||
| # optimization | |||
| If ( HAS_COTIRE ) | |||
| Cotire ( cpphibernate-test ) | |||
| EndIf ( ) | |||
| # test | |||
| If ( HAS_CMAKE_TESTS ) | |||
| Add_CMake_Test ( NAME cpphibernate TARGET cpphibernate-test ) | |||
| Else ( ) | |||
| Add_Test ( NAME cpphibernate COMMAND cpphibernate-test ) | |||
| EndIf ( ) | |||
| @@ -0,0 +1,20 @@ | |||
| #include <gtest/gtest.h> | |||
| #include <cpphibernate.h> | |||
| #include "test_schema.h" | |||
| constexpr decltype(auto) x = ::cpphibernate::mp::make_getter( | |||
| [](std::string&) { | |||
| return int { }; | |||
| }); | |||
| using namespace ::testing; | |||
| using namespace ::cpphibernate; | |||
| using namespace ::cpphibernate::schema; | |||
| TEST(cpphibernate, getHelloWorld) | |||
| { | |||
| (void)x; | |||
| // std::cout << test_schema << std::endl; | |||
| } | |||
| @@ -0,0 +1,227 @@ | |||
| #pragma once | |||
| #include <cpphibernate.h> | |||
| #include <cppcore/conversion/enum.h> | |||
| enum class test_enum | |||
| { | |||
| test0, | |||
| test1, | |||
| test2, | |||
| test3, | |||
| first = test0, | |||
| last = test3, | |||
| }; | |||
| cppcore_define_enum_value_traits( | |||
| test_enum, | |||
| { test_enum::test0, "test0" }, | |||
| { test_enum::test1, "test1" }, | |||
| { test_enum::test2, "test2" }, | |||
| { test_enum::test3, "test3" } | |||
| ); | |||
| struct test1 | |||
| { | |||
| ::cpphibernate::uuid id; | |||
| std::string str_data; | |||
| ::cpphibernate::string<64> str64_data; | |||
| cppcore::nullable<uint32_t> u32_nullable; | |||
| std::unique_ptr<uint32_t> u32_ptr_u; | |||
| std::shared_ptr<uint32_t> u32_ptr_s; | |||
| }; | |||
| struct test2 | |||
| { | |||
| ::cpphibernate::uuid id; | |||
| uint8_t u8_data; | |||
| int8_t i8_data; | |||
| uint16_t u16_data; | |||
| int16_t i16_data; | |||
| }; | |||
| struct test3 | |||
| { | |||
| ::cpphibernate::uuid id; | |||
| uint32_t u32_data; | |||
| int32_t i32_data; | |||
| uint64_t u64_data; | |||
| int64_t i64_data; | |||
| }; | |||
| struct base | |||
| { | |||
| ::cpphibernate::uuid id; | |||
| std::string name; | |||
| virtual ~base() = default; | |||
| }; | |||
| struct derived1 | |||
| : public base | |||
| { | |||
| ::cpphibernate::uuid derived1_id; | |||
| test1 test1_data; | |||
| test_enum enum_data; | |||
| }; | |||
| struct derived2 | |||
| : public base | |||
| { | |||
| ::cpphibernate::uuid derived2_id; | |||
| cppcore::nullable<test2> test2_nullable; | |||
| std::unique_ptr<test2> test2_ptr_u; | |||
| std::shared_ptr<test2> test2_ptr_s; | |||
| }; | |||
| struct derived3 | |||
| : public derived2 | |||
| { | |||
| ::cpphibernate::uuid derived3_id; | |||
| std::list<test3> test3_list; | |||
| std::vector<test3> test3_vector; | |||
| }; | |||
| struct dummy_id | |||
| { | |||
| int data; | |||
| inline dummy_id(int p_data = 0) | |||
| : data(p_data) | |||
| { } | |||
| }; | |||
| struct dummy_owner | |||
| { | |||
| ::cpphibernate::uuid id; | |||
| std::vector<dummy_id> dummies; | |||
| }; | |||
| struct double_usage_item | |||
| { | |||
| unsigned int id { 0 }; | |||
| int data { 0 }; | |||
| double_usage_item(int p_data = 0) | |||
| : data(p_data) | |||
| { } | |||
| }; | |||
| struct double_usage | |||
| { | |||
| int id { 0 }; | |||
| std::unique_ptr<double_usage_item> single_item; | |||
| std::vector<double_usage_item> multiple_items; | |||
| }; | |||
| struct double_usage_wrapper | |||
| { | |||
| int id { 0 }; | |||
| std::unique_ptr<double_usage> double_usage; | |||
| }; | |||
| constexpr decltype(auto) test_schema = cpphibernate_make_schema( | |||
| test, | |||
| cpphibernate_make_table_name( | |||
| tbl_test1, | |||
| test1, | |||
| 1, | |||
| cpphibernate_make_id (&test1::id), | |||
| cpphibernate_make_field (test1, str_data), | |||
| cpphibernate_make_field (test1, str64_data), | |||
| cpphibernate_make_field (test1, u32_nullable), | |||
| cpphibernate_make_field (test1, u32_ptr_u), | |||
| cpphibernate_make_field (test1, u32_ptr_s) | |||
| ), | |||
| cpphibernate_make_table_name( | |||
| tbl_test2, | |||
| test2, | |||
| 2, | |||
| cpphibernate_make_id (&test2::id), | |||
| cpphibernate_make_field (test2, u8_data), | |||
| cpphibernate_make_field (test2, i8_data), | |||
| cpphibernate_make_field (test2, u16_data), | |||
| cpphibernate_make_field (test2, i16_data) | |||
| ), | |||
| cpphibernate_make_table_name( | |||
| tbl_test3, | |||
| test3, | |||
| 3, | |||
| cpphibernate_make_id (&test3::id), | |||
| cpphibernate_make_field (test3, u32_data), | |||
| cpphibernate_make_field (test3, i32_data), | |||
| cpphibernate_make_field (test3, u64_data), | |||
| cpphibernate_make_field (test3, i64_data) | |||
| ), | |||
| cpphibernate_make_table_name( | |||
| tbl_base, | |||
| base, | |||
| 10, | |||
| cpphibernate_make_id (&base::id), | |||
| cpphibernate_make_field (base, name) | |||
| ), | |||
| cpphibernate_make_table_name( | |||
| tbl_derived1, | |||
| derived1, | |||
| 11, | |||
| cpphibernate_make_id (&derived1::derived1_id), | |||
| cpphibernate_make_field (derived1, test1_data), | |||
| cpphibernate_make_field (derived1, enum_data) | |||
| ), | |||
| cpphibernate_make_table_name( | |||
| tbl_derived2, | |||
| derived2, | |||
| 12, | |||
| cpphibernate_make_id (&derived2::derived2_id), | |||
| cpphibernate_make_field (derived2, test2_nullable), | |||
| cpphibernate_make_field (derived2, test2_ptr_u), | |||
| cpphibernate_make_field (derived2, test2_ptr_s) | |||
| ), | |||
| cpphibernate_make_table_name( | |||
| tbl_derived3, | |||
| derived3, | |||
| 13, | |||
| cpphibernate_make_id (&derived3::derived3_id), | |||
| cpphibernate_make_field (derived3, test3_list), | |||
| cpphibernate_make_field (derived3, test3_vector) | |||
| ), | |||
| cpphibernate_make_table_name( | |||
| tbl_dummy_id, | |||
| dummy_id, | |||
| 14, | |||
| cpphibernate_make_temp_id (dummy_id, ::cpphibernate::uuid), | |||
| cpphibernate_make_field (dummy_id, data) | |||
| ), | |||
| cpphibernate_make_table_name( | |||
| tbl_dummy_owner, | |||
| dummy_owner, | |||
| 15, | |||
| cpphibernate_make_id (&dummy_owner::id), | |||
| cpphibernate_make_field (dummy_owner, dummies) | |||
| ), | |||
| cpphibernate_make_table_name( | |||
| tbl_double_usage_item, | |||
| double_usage_item, | |||
| 16, | |||
| cpphibernate_make_id (&double_usage_item::id), | |||
| cpphibernate_make_field (double_usage_item, data) | |||
| ), | |||
| cpphibernate_make_table_name( | |||
| tbl_double_usage, | |||
| double_usage, | |||
| 17, | |||
| cpphibernate_make_id (&double_usage::id), | |||
| cpphibernate_make_field (double_usage, single_item), | |||
| cpphibernate_make_field (double_usage, multiple_items) | |||
| ), | |||
| cpphibernate_make_table_name( | |||
| tbl_double_usage_wrapper, | |||
| double_usage_wrapper, | |||
| 18, | |||
| cpphibernate_make_id (&double_usage_wrapper::id), | |||
| cpphibernate_make_field (double_usage_wrapper, double_usage) | |||
| ) | |||
| ); | |||