// file : odb/polymorphic-map.hxx // copyright : Copyright (c) 2005-2013 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #ifndef ODB_POLYMORPHIC_MAP_HXX #define ODB_POLYMORPHIC_MAP_HXX #include #include #include // std::move #include // std::size_t #include #include #include #include // ODB_CXX11 #include #include namespace odb { template struct polymorphic_map { typedef R root_type; typedef polymorphic_concrete_info info_type; typedef typename info_type::discriminator_type discriminator_type; polymorphic_map (): ref_count_ (1) {} const info_type& find (const std::type_info& t) const; const info_type& find (const discriminator_type& d) const; public: typedef std::map // VC bug. type_map; struct discriminator_comparator { bool operator() (const discriminator_type* x, const discriminator_type* y) const { return *x < *y; } }; typedef std::map discriminator_map; public: std::size_t ref_count_; type_map type_map_; discriminator_map discriminator_map_; }; template struct polymorphic_entry_impl { typedef R root_type; typedef object_traits_impl root_traits; typedef polymorphic_concrete_info info_type; static void insert (const info_type&); static void erase (const info_type&); }; template typename object_traits::root_type>::pointer_type create_impl () { typedef object_traits derived_traits; typedef object_traits root_traits; typedef typename derived_traits::pointer_type derived_pointer_type; typedef typename root_traits::pointer_type root_pointer_type; derived_pointer_type p ( access::object_factory::create ()); // Implicit downcast. // #ifdef ODB_CXX11 root_pointer_type r (std::move (p)); #else root_pointer_type r (p); #endif return r; } template struct dispatch_load { static void call (database& db, T& obj, std::size_t d) { object_traits_impl::load_ (db, obj, d); } }; template struct dispatch_load { static void call (database&, R&, std::size_t) { assert (false); } }; template struct dispatch_persist { static void call (database& db, const T& obj) { // Top-level call, no dynamic type checking. // object_traits_impl::persist (db, obj, true, false); } }; template struct dispatch_persist { static void call (database& db, const T& obj) { // Top-level call, no dynamic type checking. // object_traits_impl::persist ( db, const_cast (obj), true, false); } }; template bool dispatch_impl ( typename polymorphic_concrete_info< typename object_traits::root_type>::call_type c, database& db, const typename object_traits::root_type* pobj, const void* arg) { typedef object_traits_impl derived_traits; typedef typename derived_traits::root_type root_type; typedef object_traits_impl root_traits; typedef typename root_traits::id_type id_type; typedef polymorphic_concrete_info info_type; bool r (false); switch (c) { case info_type::call_callback: { derived_traits::callback ( db, *const_cast (static_cast (pobj)), *static_cast (arg)); break; } case info_type::call_persist: { dispatch_persist::call ( db, *static_cast (pobj)); break; } case info_type::call_update: { derived_traits::update ( db, *static_cast (pobj), true, // Top-level call. false); // No dynamic type checking. break; } case info_type::call_find: { r = derived_traits::find ( db, *static_cast (arg), *const_cast (static_cast (pobj)), false); // No dynamic type checking. break; } case info_type::call_reload: { r = derived_traits::reload ( db, *const_cast (static_cast (pobj)), false); // No dynamic type checking. break; } case info_type::call_load: { dispatch_load::call ( db, *const_cast (static_cast (pobj)), *static_cast (arg)); break; } case info_type::call_erase: { if (pobj != 0) derived_traits::erase ( db, *static_cast (pobj), true, // Top-level call. false); // No dynamic type checking. else derived_traits::erase ( db, *static_cast (arg), true, // Top-level call. false); // No dynamic type checking. break; } } return r; } template void section_load_impl (odb::connection& conn, typename object_traits::root_type& obj, bool top) { typedef object_traits_impl derived_traits; typedef typename derived_traits::statements_type statements_type; typedef typename statements_type::connection_type connection_type; connection_type& c (static_cast (conn)); statements_type& sts (c.statement_cache ().template find_object ()); ST::load (sts.extra_statement_cache (), static_cast (obj), top); } template void section_update_impl (odb::connection& conn, const typename object_traits::root_type& obj) { typedef object_traits_impl derived_traits; typedef typename derived_traits::statements_type statements_type; typedef typename statements_type::connection_type connection_type; connection_type& c (static_cast (conn)); statements_type& sts (c.statement_cache ().template find_object ()); ST::update (sts.extra_statement_cache (), static_cast (obj)); } } #include #include #include #endif // ODB_POLYMORPHIC_MAP_HXX