aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2012-09-03 12:02:29 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2012-09-03 12:02:29 +0200
commit7b884d89ed25337ac9ad26487f89c750435472af (patch)
treed121a20c7f6fc67b150e0d7e09b2e19834bd0f65
parent705d9bb3d1a1a74dbecc0ed1fd7b3bd1d1fea1e6 (diff)
Add support for Boost Multi-Index container in Boost profile
-rw-r--r--odb/boost.options1
-rw-r--r--odb/boost/multi-index.options8
-rw-r--r--odb/boost/multi-index/container-traits.hxx214
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