From 26e36b3a9d7b49d46ecfa69b447482251acba8ac Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Wed, 24 Jan 2024 16:53:38 +0300 Subject: Turn libodb repository into package for muti-package repository --- libodb/odb/traits.hxx | 317 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 317 insertions(+) create mode 100644 libodb/odb/traits.hxx (limited to 'libodb/odb/traits.hxx') diff --git a/libodb/odb/traits.hxx b/libodb/odb/traits.hxx new file mode 100644 index 0000000..2c6f5d6 --- /dev/null +++ b/libodb/odb/traits.hxx @@ -0,0 +1,317 @@ +// file : odb/traits.hxx +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_TRAITS_HXX +#define ODB_TRAITS_HXX + +#include + +#include +#include + +namespace odb +{ + // Fallback dummy for non-persistent classes. It is necessary to allow + // the C++ compiler to instantiate persist(), etc., signatures in class + // database when T is a pointer (raw, smart). The overloads that use + // these dummy would never actually be selected by the compiler. + // + template + class access::object_traits + { + // If a C++ compiler issues an error pointing to this class and saying + // that it is missing some declaration, then you are most likely trying + // to perform a database operation on a C++ type that is not a persistent + // object. Or you forgot to include the corresponding -odb.hxx file. + // + public: + struct id_type {}; + typedef T object_type; + typedef T* pointer_type; + + static const bool polymorphic = false; + }; + + template + class access::object_factory + { + public: + typedef T object_type; + typedef P pointer_type; + + static P + create () + { + // By default use pointer-specific construction. + // + return pointer_factory::create (); + } + }; + + template + class access::view_factory + { + public: + typedef T view_type; + typedef P pointer_type; + + static P + create () + { + // By default use pointer-specific construction. + // + return pointer_factory::create (); + } + }; + + template + class access::pointer_factory + { + public: + typedef T value_type; + typedef P pointer_type; + + + // Suppress bogus use-after-free introduced in GCC 12 (GCC bug #105327). + // +#if defined(__GNUC__) && !defined(__clang__) && __GNUC__ >= 12 +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wuse-after-free" +#endif + + static P + create () + { + void* v (pointer_traits

::allocate (sizeof (T))); + mem_guard g (v); + P p (new (v) T); + g.release (); + return p; + } + +#if defined(__GNUC__) && !defined(__clang__) && __GNUC__ >= 12 +#pragma GCC diagnostic pop +#endif + + private: + struct mem_guard + { + mem_guard (void* p): p_ (p) {} + ~mem_guard () {if (p_) pointer_traits

::free (p_);} + void release () {p_ = 0;} + void* p_; + }; + }; + + // + // class_traits + // + enum class_kind + { + class_object, + class_view, + class_other + }; + + template + struct class_traits + { + static const class_kind kind = class_other; + }; + + template + struct class_traits + { + static const class_kind kind = class_traits::kind; + }; + + // + // object_traits + // + + template + // + // If a C++ compiler issues an error pointing to this struct and + // saying that it is incomplete, then you are most likely trying to + // perform a database operation on a C++ type that is not a persistent + // object. Or you forgot to include the corresponding -odb.hxx file. + // + struct object_traits: + access::object_traits, + access::object_factory::pointer_type> + { + typedef + odb::pointer_traits::pointer_type> + pointer_traits; + + typedef typename access::object_traits::object_type object_type; + typedef typename access::object_traits::pointer_type pointer_type; + typedef typename pointer_traits::const_pointer_type const_pointer_type; + }; + + // Specialization for const objects. It only defines the id, object, + // pointer, and const_pointer types with pointer and const_pointer + // being the same. The idea is to only use this specialization in the + // interfaces, with the implementations detecting this situation and + // using the non-const object_traits version. + // + template + struct object_traits + { + private: + typedef + odb::pointer_traits::pointer_type> + pointer_traits; + + public: + typedef typename access::object_traits::id_type id_type; + typedef typename access::object_traits::object_type object_type; + typedef typename pointer_traits::const_pointer_type const_pointer_type; + typedef const_pointer_type pointer_type; + + static const bool polymorphic = access::object_traits::polymorphic; + }; + + // Specialization for section to allow instantiation of all the load() + // signature. + // + template <> + struct object_traits

{}; + + template + // + // If a C++ compiler issues an error pointing to this struct and + // saying that it is incomplete, then you are most likely trying to + // perform a database operation on a C++ type that is not a persistent + // object. Or you forgot to include the corresponding -odb.hxx file. + // + struct object_traits_impl: + access::object_traits_impl, + access::object_factory::pointer_type> + { + typedef + odb::pointer_traits::pointer_type> + pointer_traits; + + typedef typename access::object_traits::object_type object_type; + typedef typename access::object_traits::pointer_type pointer_type; + typedef typename pointer_traits::const_pointer_type const_pointer_type; + }; + + // + // view_traits + // + + template + // + // If a C++ compiler issues an error pointing to this struct and + // saying that it is incomplete, then you are most likely trying to + // perform a database operation on a C++ type that is not a view + // Or you forgot to include the corresponding -odb.hxx file. + // + struct view_traits: + access::view_traits, + access::view_factory::pointer_type> + { + typedef + odb::pointer_traits::pointer_type> + pointer_traits; + + typedef typename access::view_traits::view_type view_type; + typedef typename access::view_traits::pointer_type pointer_type; + }; + + // Specialization for const views. It only defines the view, pointer, + // and const_pointer types with pointer and const_pointer being the + // same. Similar to objects, the idea is to only use this specialization + // in the interfaces, with the implementations detecting this situation + // and using the non-const view_traits version. + // + template + struct view_traits + { + private: + typedef + odb::pointer_traits::pointer_type> + pointer_traits; + + public: + typedef typename access::view_traits::view_type view_type; + typedef typename pointer_traits::const_pointer_type const_pointer_type; + typedef const_pointer_type pointer_type; + }; + + template + // + // If a C++ compiler issues an error pointing to this struct and + // saying that it is incomplete, then you are most likely trying to + // perform a database operation on a C++ type that is not a view + // Or you forgot to include the corresponding -odb.hxx file. + // + struct view_traits_impl: + access::view_traits_impl, + access::view_factory::pointer_type> + { + typedef + odb::pointer_traits::pointer_type> + pointer_traits; + + typedef typename access::view_traits::view_type view_type; + typedef typename access::view_traits::pointer_type pointer_type; + }; + + // + // composite_value_traits + // + + template + struct composite_value_traits: access::composite_value_traits + { + }; + + // + // Get root image from a polymorphic image chain. + // + + template + struct root_image_impl + { + typedef root_image_impl base_type; + typedef typename base_type::image_type image_type; + + static image_type& + get (typename T::image_type& i) {return base_type::get (*i.base);} + }; + + template + struct root_image_impl + { + typedef typename T::image_type image_type; + + static image_type& + get (image_type& i) {return i;} + }; + + template + struct root_image + { + typedef root_image_impl impl_type; + typedef typename impl_type::image_type image_type; + + static image_type& + get (typename T::image_type& i) {return impl_type::get (i);} + }; + + template + struct root_image + { + typedef typename T::image_type image_type; + + static image_type& + get (image_type& i) {return i;} + }; +} + +#include + +#endif // ODB_TRAITS_HXX -- cgit v1.1