diff options
Diffstat (limited to 'boost/flyweight/detail/flyweight_core.hpp')
-rw-r--r-- | boost/flyweight/detail/flyweight_core.hpp | 252 |
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 |