diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2012-09-03 12:02:29 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2012-09-03 12:02:29 +0200 |
commit | 7b884d89ed25337ac9ad26487f89c750435472af (patch) | |
tree | d121a20c7f6fc67b150e0d7e09b2e19834bd0f65 | |
parent | 705d9bb3d1a1a74dbecc0ed1fd7b3bd1d1fea1e6 (diff) |
Add support for Boost Multi-Index container in Boost profile
-rw-r--r-- | odb/boost.options | 1 | ||||
-rw-r--r-- | odb/boost/multi-index.options | 8 | ||||
-rw-r--r-- | odb/boost/multi-index/container-traits.hxx | 214 |
3 files changed, 223 insertions, 0 deletions
diff --git a/odb/boost.options b/odb/boost.options index 32b9239..460dd77 100644 --- a/odb/boost.options +++ b/odb/boost.options @@ -6,3 +6,4 @@ --profile boost/optional --profile boost/unordered --profile boost/date-time +--profile boost/multi-index diff --git a/odb/boost/multi-index.options b/odb/boost/multi-index.options new file mode 100644 index 0000000..a60a47d --- /dev/null +++ b/odb/boost/multi-index.options @@ -0,0 +1,8 @@ +# file : odb/boost/multi-index.options +# copyright : Copyright (c) 2009-2012 Code Synthesis Tools CC +# license : GNU GPL v2; see accompanying LICENSE file + +--profile boost/version + +--odb-epilogue '#include <odb/boost/multi-index/container-traits.hxx>' +--hxx-prologue '#include <odb/boost/multi-index/container-traits.hxx>' diff --git a/odb/boost/multi-index/container-traits.hxx b/odb/boost/multi-index/container-traits.hxx new file mode 100644 index 0000000..5f5616a --- /dev/null +++ b/odb/boost/multi-index/container-traits.hxx @@ -0,0 +1,214 @@ +// file : odb/boost/unordered/container-traits.hxx +// copyright : Copyright (c) 2009-2012 Code Synthesis Tools CC +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_BOOST_UNORDERED_CONTAINER_TRAITS_HXX +#define ODB_BOOST_UNORDERED_CONTAINER_TRAITS_HXX + +#include <boost/version.hpp> + +// Multi-index container is available since 1.32.0. +// +#if BOOST_VERSION >= 103200 + +#include <odb/pre.hxx> + +#include <utility> // std::move + +#include <boost/mpl/find_if.hpp> +#include <boost/mpl/distance.hpp> +#include <boost/mpl/begin_end.hpp> + +#include <boost/multi_index_container.hpp> +#include <boost/multi_index/sequenced_index.hpp> +#include <boost/multi_index/random_access_index.hpp> + +#include <odb/container-traits.hxx> +#include <odb/details/config.hxx> // ODB_CXX11 + +namespace odb +{ + // Multi-index container can be ordered or set. Whether it is ordered + // depends on whether it has any sequenced or random_access indexes. + // If it is ordered, then we need to use one of these indexes to store + // elements in a specific order. Otherwise, we can use the first index + // since the order of elements in the database is not important. Note + // that there is a terminology clash between ODB and Boost multi-index. + // What ODB calls ordered containers, multi-index calls sequenced and + // random_access. And what ODB calls set containers, multi-index calls + // ordered and hashed. + // + + // Test whether index is ordered. + // + template <typename I> + struct multi_index_ordered + { + static const bool value = false; + }; + + template <typename T> + struct multi_index_ordered< ::boost::multi_index::sequenced<T> > + { + static const bool value = true; + }; + + template <typename T> + struct multi_index_ordered< ::boost::multi_index::random_access<T> > + { + static const bool value = true; + }; + + // Get the index of the first ordered sub-index or -1 if none exists. + // + template <typename B, typename I, typename E> + struct multi_index_ordered_index + { + static const int value = ::boost::mpl::distance<B, I>::value; + }; + + template <typename B, typename E> + struct multi_index_ordered_index<B, E, E> + { + static const int value = -1; + }; + + template <typename V, + typename ISP, + typename A, + int N = + multi_index_ordered_index< + typename ::boost::mpl::begin<ISP>::type, + typename ::boost::mpl::find_if< + ISP, multi_index_ordered< ::boost::mpl::_1 > >::type, + typename ::boost::mpl::end<ISP>::type>::value> + class multi_index_traits + { + public: + static container_kind const kind = ck_ordered; + + typedef ::boost::multi_index_container<V, ISP, A> container_type; + typedef typename container_type::template nth_index<N>::type + ordered_container_type; + + typedef V value_type; + typedef typename ordered_container_type::size_type index_type; + + typedef ordered_functions<index_type, value_type> functions; + + public: + static void + persist (const container_type& c, const functions& f) + { + const ordered_container_type& oc (c.template get<N> ()); + index_type i (0); + for (typename ordered_container_type::const_iterator j (oc.begin ()), + e (oc.end ()); j != e; ++j) + f.insert_one (i++, *j); + } + + static void + load (container_type& c, bool more, const functions& f) + { + ordered_container_type& oc (c.template get<N> ()); + oc.clear (); + + while (more) + { + index_type dummy; + value_type v; + more = f.load_all (dummy, v); +#ifdef ODB_CXX11 + oc.push_back (std::move (v)); +#else + oc.push_back (v); +#endif + } + } + + static void + update (const container_type& c, const functions& f) + { + f.delete_all (); + + const ordered_container_type& oc (c.template get<N> ()); + index_type i (0); + for (typename ordered_container_type::const_iterator j (oc.begin ()), + e (oc.end ()); j != e; ++j) + f.insert_one (i++, *j); + } + + static void + erase (const functions& f) + { + f.delete_all (); + } + }; + + // Set specialization. + // + template <typename V, typename ISP, typename A> + class multi_index_traits<V, ISP, A, -1> + { + public: + static container_kind const kind = ck_set; + + typedef ::boost::multi_index_container<V, ISP, A> container_type; + typedef V value_type; + + typedef set_functions<value_type> functions; + + public: + static void + persist (const container_type& c, const functions& f) + { + for (typename container_type::const_iterator i (c.begin ()), + e (c.end ()); i != e; ++i) + f.insert_one (*i); + } + + static void + load (container_type& c, bool more, const functions& f) + { + c.clear (); + + while (more) + { + value_type v; + more = f.load_all (v); +#ifdef ODB_CXX11 + c.insert (std::move (v)); +#else + c.insert (v); +#endif + } + } + + static void + update (const container_type& c, const functions& f) + { + f.delete_all (); + + for (typename container_type::const_iterator i (c.begin ()), + e (c.end ()); i != e; ++i) + f.insert_one (*i); + } + + static void + erase (const functions& f) + { + f.delete_all (); + } + }; + + template <typename V, typename ISP, typename A> + class access::container_traits< ::boost::multi_index_container<V, ISP, A> > + : public multi_index_traits<V, ISP, A> + { + }; +} + +#include <odb/post.hxx> + +#endif // BOOST_VERSION +#endif // ODB_BOOST_UNORDERED_CONTAINER_TRAITS_HXX |