From 1f217e38f7507758da1d33d46e675e801621aa38 Mon Sep 17 00:00:00 2001 From: Michael Shepanski Date: Thu, 30 Oct 2014 15:21:32 +1100 Subject: Allow lambdas & std::functions as query factories with C++-98 builds of libodb --- odb/schema-catalog.hxx | 164 +++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 144 insertions(+), 20 deletions(-) (limited to 'odb/schema-catalog.hxx') diff --git a/odb/schema-catalog.hxx b/odb/schema-catalog.hxx index 7d675fe..510126a 100644 --- a/odb/schema-catalog.hxx +++ b/odb/schema-catalog.hxx @@ -13,7 +13,9 @@ #include // std::size_t #ifdef ODB_CXX11 -# include // std::function +# include // std::move +# include // std::function +# include // std::enable_if, std::is_convertible #endif #include // schema_version, odb::core @@ -74,11 +76,11 @@ namespace odb schema_version = 0, const std::string& name = ""); -#ifdef ODB_CXX11 - typedef std::function data_migration_function_type; -#else - typedef void (*data_migration_function_type) (database&); -#endif + typedef void data_migration_function_type (database&); + typedef data_migration_function_type* data_migration_function_ptr; + + typedef details::function_wrapper + data_migration_function_wrapper; // The following three variants of the registration functions make // sure that the version is greater that the base model version. @@ -87,38 +89,59 @@ namespace odb // // Data migration functions are called in the order of registration. // +#ifndef ODB_CXX11 template static void - data_migration_function (data_migration_function_type f, + data_migration_function (data_migration_function_ptr f, const std::string& name = "") { data_migration_function (id_common, f, name); } +#else + template + static typename std::enable_if< + std::is_convertible< + F, std::function>::value, void>::type + data_migration_function (F f, const std::string& name = "") + { + data_migration_function (id_common, std::move (f), name); + } +#endif + // Database-specific data migration. // +#ifndef ODB_CXX11 template static void data_migration_function (database& db, - data_migration_function_type f, + data_migration_function_ptr f, const std::string& name = "") { data_migration_function (db.id (), f, name); } +#else + template + static typename std::enable_if< + std::is_convertible< + F, std::function>::value, void>::type + data_migration_function (database& db, F f, const std::string& name = "") + { + data_migration_function (db.id (), std::move (f), name); + } +#endif +#ifndef ODB_CXX11 template static void data_migration_function (database_id id, - data_migration_function_type f, + data_migration_function_ptr f, const std::string& name = "") { // If the data migration version is below the base model version // then it will never be called. // -#ifdef ODB_CXX11 - static_assert (v > base || base == 0, - "data migration function is no longer necessary"); -#else + // Poor man's static_assert. // typedef details::meta::static_assert_test<(v > base || base == 0)> @@ -126,36 +149,109 @@ namespace odb char sa [sizeof (data_migration_function_is_no_longer_necessary)]; ODB_POTENTIALLY_UNUSED (sa); -#endif data_migration_function (id, v, f, name); } +#else + template + static typename std::enable_if< + std::is_convertible< + F, std::function>::value, void>::type + data_migration_function (database_id id, F f, const std::string& name = "") + { + // If the data migration version is below the base model version + // then it will never be called. + // + static_assert (v > base || base == 0, + "data migration function is no longer necessary"); + + data_migration_function (id, v, std::move (f), name); + } +#endif // The same as above but take the version as an argument and do // not check whether it is greater than the base model version. // +#ifndef ODB_CXX11 static void data_migration_function (schema_version v, - data_migration_function_type f, + data_migration_function_ptr f, const std::string& name = "") { data_migration_function (id_common, v, f, name); } +#else + template + static typename std::enable_if< + std::is_convertible< + F, std::function>::value, void>::type + data_migration_function (schema_version v, + F f, + const std::string& name = "") + { + data_migration_function (id_common, v, std::move (f), name); + } +#endif +#ifndef ODB_CXX11 static void data_migration_function (database& db, schema_version v, - data_migration_function_type f, + data_migration_function_ptr f, const std::string& name = "") { data_migration_function (db.id (), v, f, name); } +#else + template + static typename std::enable_if< + std::is_convertible< + F, std::function>::value, void>::type + data_migration_function (database& db, + schema_version v, + F f, + const std::string& name = "") + { + data_migration_function (db.id (), v, std::move (f), name); + } +#endif + +#ifndef ODB_CXX11 + static void + data_migration_function (database_id i, + schema_version v, + data_migration_function_ptr f, + const std::string& name = "") + { + data_migration_function (i, + v, + data_migration_function_wrapper (f), + name); + } +#else + template + static typename std::enable_if< + std::is_convertible< + F, std::function>::value, void>::type + data_migration_function (database_id i, + schema_version v, + F f, + const std::string& name = "") + { + data_migration_function ( + i, + v, + data_migration_function_wrapper (std::move (f)), + name); + } +#endif + private: static void data_migration_function (database_id, schema_version, - data_migration_function_type, - const std::string& name = ""); + data_migration_function_wrapper, + const std::string& name); // Combined schema and data migration. // @@ -244,17 +340,45 @@ namespace odb { typedef schema_catalog::data_migration_function_type function_type; - data_migration_entry (function_type f, const std::string& name = "") +#ifndef ODB_CXX11 + data_migration_entry (function_type* f, const std::string& name = "") { schema_catalog::data_migration_function (f, name); } +#else + template + data_migration_entry (F f, + const std::string& name = "", + typename std::enable_if>::value> + ::type* = 0) + { + schema_catalog::data_migration_function (std::move (f), name); + } +#endif +#ifndef ODB_CXX11 data_migration_entry (database_id id, - function_type f, + function_type *f, const std::string& name = "") { schema_catalog::data_migration_function (id, v, f, name); } +#else + template + data_migration_entry (database_id id, + F f, + const std::string& name = "", + typename std::enable_if>::value> + ::type* = 0) + { + schema_catalog::data_migration_function (id, + v, + std::move (f), + name); + } +#endif }; namespace common -- cgit v1.1