summaryrefslogtreecommitdiff
path: root/boost/flyweight/detail/flyweight_core.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/flyweight/detail/flyweight_core.hpp')
-rw-r--r--boost/flyweight/detail/flyweight_core.hpp252
1 files changed, 252 insertions, 0 deletions
diff --git a/boost/flyweight/detail/flyweight_core.hpp b/boost/flyweight/detail/flyweight_core.hpp
new file mode 100644
index 0000000000..a55c43e462
--- /dev/null
+++ b/boost/flyweight/detail/flyweight_core.hpp
@@ -0,0 +1,252 @@
+/* Copyright 2006-2009 Joaquin M Lopez Munoz.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ *
+ * See http://www.boost.org/libs/flyweight for library home page.
+ */
+
+#ifndef BOOST_FLYWEIGHT_DETAIL_FLYWEIGHT_CORE_HPP
+#define BOOST_FLYWEIGHT_DETAIL_FLYWEIGHT_CORE_HPP
+
+#if defined(_MSC_VER)&&(_MSC_VER>=1200)
+#pragma once
+#endif
+
+#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
+#include <boost/detail/no_exceptions_support.hpp>
+#include <boost/detail/workaround.hpp>
+#include <boost/mpl/apply.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+
+#if BOOST_WORKAROUND(BOOST_MSVC,BOOST_TESTED_AT(1400))
+#pragma warning(push)
+#pragma warning(disable:4101) /* unreferenced local vars */
+#endif
+
+/* flyweight_core provides the inner implementation of flyweight<> by
+ * weaving together a value policy, a flyweight factory, a holder for the
+ * factory,a tracking policy and a locking policy.
+ */
+
+namespace boost{
+
+namespace flyweights{
+
+namespace detail{
+
+template<
+ typename ValuePolicy,typename Tag,typename TrackingPolicy,
+ typename FactorySpecifier,typename LockingPolicy,typename HolderSpecifier
+>
+class flyweight_core;
+
+template<
+ typename ValuePolicy,typename Tag,typename TrackingPolicy,
+ typename FactorySpecifier,typename LockingPolicy,typename HolderSpecifier
+>
+struct flyweight_core_tracking_helper
+{
+private:
+ typedef flyweight_core<
+ ValuePolicy,Tag,TrackingPolicy,
+ FactorySpecifier,LockingPolicy,
+ HolderSpecifier
+ > core;
+ typedef typename core::handle_type handle_type;
+ typedef typename core::entry_type entry_type;
+
+public:
+ static const entry_type& entry(const handle_type& h)
+ {
+ return core::entry(h);
+ }
+
+ template<typename Checker>
+ static void erase(const handle_type& h,Checker check)
+ {
+ typedef typename core::lock_type lock_type;
+ lock_type lock(core::mutex());
+ if(check(h))core::factory().erase(h);
+ }
+};
+
+template<
+ typename ValuePolicy,typename Tag,typename TrackingPolicy,
+ typename FactorySpecifier,typename LockingPolicy,typename HolderSpecifier
+>
+class flyweight_core
+{
+public:
+ typedef typename ValuePolicy::key_type key_type;
+ typedef typename ValuePolicy::value_type value_type;
+ typedef typename ValuePolicy::rep_type rep_type;
+ typedef typename mpl::apply2<
+ typename TrackingPolicy::entry_type,
+ rep_type,
+ key_type
+ >::type entry_type;
+ typedef typename mpl::apply2<
+ FactorySpecifier,
+ entry_type,
+ key_type
+ >::type factory_type;
+ typedef typename factory_type::handle_type base_handle_type;
+ typedef typename mpl::apply2<
+ typename TrackingPolicy::handle_type,
+ base_handle_type,
+ flyweight_core_tracking_helper<
+ ValuePolicy,Tag,TrackingPolicy,
+ FactorySpecifier,LockingPolicy,
+ HolderSpecifier
+ >
+ >::type handle_type;
+ typedef typename LockingPolicy::mutex_type mutex_type;
+ typedef typename LockingPolicy::lock_type lock_type;
+
+ static bool init()
+ {
+ if(static_initializer)return true;
+ else{
+ holder_arg& a=holder_type::get();
+ static_factory_ptr=&a.factory;
+ static_mutex_ptr=&a.mutex;
+ static_initializer=(static_factory_ptr!=0);
+ return static_initializer;
+ }
+ }
+
+ /* insert overloads*/
+
+#define BOOST_FLYWEIGHT_PERFECT_FWD_NAME static handle_type insert
+#define BOOST_FLYWEIGHT_PERFECT_FWD_BODY(n) \
+{ \
+ return insert_rep(rep_type(BOOST_PP_ENUM_PARAMS(n,t))); \
+}
+#include <boost/flyweight/detail/perfect_fwd.hpp>
+
+ static handle_type insert(const value_type& x){return insert_value(x);}
+ static handle_type insert(value_type& x){return insert_value(x);}
+
+ static const entry_type& entry(const base_handle_type& h)
+ {
+ return factory().entry(h);
+ }
+
+ static const value_type& value(const handle_type& h)
+ {
+ return static_cast<const rep_type&>(entry(h));
+ }
+
+ static const key_type& key(const handle_type& h)
+ {
+ return static_cast<const rep_type&>(entry(h));
+ }
+
+ static factory_type& factory()
+ {
+ return *static_factory_ptr;
+ }
+
+ static mutex_type& mutex()
+ {
+ return *static_mutex_ptr;
+ }
+
+private:
+ struct holder_arg
+ {
+ factory_type factory;
+ mutex_type mutex;
+ };
+ typedef typename mpl::apply1<
+ HolderSpecifier,
+ holder_arg
+ >::type holder_type;
+
+ static handle_type insert_rep(const rep_type& x)
+ {
+ init();
+ entry_type e(x);
+ lock_type lock(mutex());
+ base_handle_type h(factory().insert(e));
+ BOOST_TRY{
+ ValuePolicy::construct_value(
+ static_cast<const rep_type&>(entry(h)));
+ }
+ BOOST_CATCH(...){
+ factory().erase(h);
+ BOOST_RETHROW;
+ }
+ BOOST_CATCH_END
+ return static_cast<handle_type>(h);
+ }
+
+ static handle_type insert_value(const value_type& x)
+ {
+ init();
+ entry_type e((rep_type(x)));
+ lock_type lock(mutex());
+ base_handle_type h(factory().insert(e));
+ BOOST_TRY{
+ ValuePolicy::copy_value(
+ static_cast<const rep_type&>(entry(h)));
+ }
+ BOOST_CATCH(...){
+ factory().erase(h);
+ BOOST_RETHROW;
+ }
+ BOOST_CATCH_END
+ return static_cast<handle_type>(h);
+ }
+
+ static bool static_initializer;
+ static factory_type* static_factory_ptr;
+ static mutex_type* static_mutex_ptr;
+};
+
+template<
+ typename ValuePolicy,typename Tag,typename TrackingPolicy,
+ typename FactorySpecifier,typename LockingPolicy,typename HolderSpecifier
+>
+bool
+flyweight_core<
+ ValuePolicy,Tag,TrackingPolicy,
+ FactorySpecifier,LockingPolicy,HolderSpecifier>::static_initializer=
+ flyweight_core<
+ ValuePolicy,Tag,TrackingPolicy,
+ FactorySpecifier,LockingPolicy,HolderSpecifier>::init();
+
+template<
+ typename ValuePolicy,typename Tag,typename TrackingPolicy,
+ typename FactorySpecifier,typename LockingPolicy,typename HolderSpecifier
+>
+typename flyweight_core<
+ ValuePolicy,Tag,TrackingPolicy,
+ FactorySpecifier,LockingPolicy,HolderSpecifier>::factory_type*
+flyweight_core<
+ ValuePolicy,Tag,TrackingPolicy,
+ FactorySpecifier,LockingPolicy,HolderSpecifier>::static_factory_ptr=0;
+
+template<
+ typename ValuePolicy,typename Tag,typename TrackingPolicy,
+ typename FactorySpecifier,typename LockingPolicy,typename HolderSpecifier
+>
+typename flyweight_core<
+ ValuePolicy,Tag,TrackingPolicy,
+ FactorySpecifier,LockingPolicy,HolderSpecifier>::mutex_type*
+flyweight_core<
+ ValuePolicy,Tag,TrackingPolicy,
+ FactorySpecifier,LockingPolicy,HolderSpecifier>::static_mutex_ptr=0;
+
+} /* namespace flyweights::detail */
+
+} /* namespace flyweights */
+
+} /* namespace boost */
+
+#if BOOST_WORKAROUND(BOOST_MSVC,BOOST_TESTED_AT(1400))
+#pragma warning(pop)
+#endif
+
+#endif