Chris@101: /* Copyright 2006-2014 Joaquin M Lopez Munoz. Chris@16: * Distributed under the Boost Software License, Version 1.0. Chris@16: * (See accompanying file LICENSE_1_0.txt or copy at Chris@16: * http://www.boost.org/LICENSE_1_0.txt) Chris@16: * Chris@16: * See http://www.boost.org/libs/flyweight for library home page. Chris@16: */ Chris@16: Chris@16: #ifndef BOOST_FLYWEIGHT_ASSOC_CONTAINER_FACTORY_HPP Chris@16: #define BOOST_FLYWEIGHT_ASSOC_CONTAINER_FACTORY_HPP Chris@16: Chris@101: #if defined(_MSC_VER) Chris@16: #pragma once Chris@16: #endif Chris@16: Chris@16: #include /* keep it first to prevent nasty warns in MSVC */ Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@101: #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) Chris@101: #include Chris@101: #endif Chris@101: Chris@16: namespace boost{namespace flyweights{namespace detail{ Chris@16: BOOST_FLYWEIGHT_NESTED_XXX_IF_NOT_PLACEHOLDER_EXPRESSION_DEF(iterator); Chris@16: BOOST_FLYWEIGHT_NESTED_XXX_IF_NOT_PLACEHOLDER_EXPRESSION_DEF(value_type); Chris@16: }}} /* namespace boost::flyweights::detail */ Chris@16: Chris@16: /* Factory class using a given associative container. Chris@16: */ Chris@16: Chris@16: namespace boost{ Chris@16: Chris@16: namespace flyweights{ Chris@16: Chris@16: template Chris@16: class assoc_container_factory_class:public factory_marker Chris@16: { Chris@16: public: Chris@16: /* When assoc_container_factory_class is an MPL placeholder Chris@16: * expression, referring to Container::iterator and Container::value_type Chris@16: * force the MPL placeholder expression Container to be instantiated, which Chris@16: * is wasteful and can fail in concept-checked STL implementations. Chris@16: * We protect ourselves against this circumstance. Chris@16: */ Chris@16: Chris@16: typedef typename detail::nested_iterator_if_not_placeholder_expression< Chris@16: Container Chris@16: >::type handle_type; Chris@16: typedef typename detail::nested_value_type_if_not_placeholder_expression< Chris@16: Container Chris@16: >::type entry_type; Chris@16: Chris@16: handle_type insert(const entry_type& x) Chris@16: { Chris@16: return cont.insert(x).first; Chris@16: } Chris@16: Chris@101: #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) Chris@101: handle_type insert(entry_type&& x) Chris@101: { Chris@101: return cont.insert(std::move(x)).first; Chris@101: } Chris@101: #endif Chris@101: Chris@16: void erase(handle_type h) Chris@16: { Chris@16: cont.erase(h); Chris@16: } Chris@16: Chris@16: static const entry_type& entry(handle_type h){return *h;} Chris@16: Chris@16: private: Chris@16: /* As above, avoid instantiating Container if it is an Chris@16: * MPL placeholder expression. Chris@16: */ Chris@16: Chris@16: typedef typename mpl::if_< Chris@16: detail::is_placeholder_expression, Chris@16: int, Chris@16: Container Chris@16: >::type container_type; Chris@16: container_type cont; Chris@16: Chris@16: public: Chris@16: typedef assoc_container_factory_class type; Chris@16: BOOST_MPL_AUX_LAMBDA_SUPPORT(1,assoc_container_factory_class,(Container)) Chris@16: }; Chris@16: Chris@16: /* assoc_container_factory_class specifier */ Chris@16: Chris@16: template< Chris@16: typename ContainerSpecifier Chris@16: BOOST_FLYWEIGHT_NOT_A_PLACEHOLDER_EXPRESSION_DEF Chris@16: > Chris@16: struct assoc_container_factory:factory_marker Chris@16: { Chris@16: template Chris@16: struct apply Chris@16: { Chris@16: typedef assoc_container_factory_class< Chris@16: typename mpl::apply2::type Chris@16: > type; Chris@16: }; Chris@16: }; Chris@16: Chris@16: } /* namespace flyweights */ Chris@16: Chris@16: } /* namespace boost */ Chris@16: Chris@16: #endif