1 /* Copyright 2006-2014 Joaquin M Lopez Munoz. 2 * Distributed under the Boost Software License, Version 1.0. 3 * (See accompanying file LICENSE_1_0.txt or copy at 4 * http://www.boost.org/LICENSE_1_0.txt) 5 * 6 * See http://www.boost.org/libs/flyweight for library home page. 7 */ 8 9 #ifndef BOOST_FLYWEIGHT_HASHED_FACTORY_HPP 10 #define BOOST_FLYWEIGHT_HASHED_FACTORY_HPP 11 12 #if defined(_MSC_VER) 13 #pragma once 14 #endif 15 16 #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ 17 #include <boost/flyweight/factory_tag.hpp> 18 #include <boost/flyweight/hashed_factory_fwd.hpp> 19 #include <boost/multi_index_container.hpp> 20 #include <boost/multi_index/identity.hpp> 21 #include <boost/multi_index/hashed_index.hpp> 22 #include <boost/mpl/aux_/lambda_support.hpp> 23 #include <boost/mpl/if.hpp> 24 25 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) 26 #include <utility> 27 #endif 28 29 /* Flyweight factory based on a hashed container implemented 30 * with Boost.MultiIndex. 31 */ 32 33 namespace boost{ 34 35 namespace flyweights{ 36 37 template< 38 typename Entry,typename Key, 39 typename Hash,typename Pred,typename Allocator 40 > 41 class hashed_factory_class:public factory_marker 42 { 43 struct index_list: 44 boost::mpl::vector1< 45 multi_index::hashed_unique< 46 multi_index::identity<Entry>, 47 typename boost::mpl::if_< 48 mpl::is_na<Hash>, 49 hash<Key>, 50 Hash 51 >::type, 52 typename boost::mpl::if_< 53 mpl::is_na<Pred>, 54 std::equal_to<Key>, 55 Pred 56 >::type 57 > 58 > 59 {}; 60 61 typedef multi_index::multi_index_container< 62 Entry, 63 index_list, 64 typename boost::mpl::if_< 65 mpl::is_na<Allocator>, 66 std::allocator<Entry>, 67 Allocator 68 >::type 69 > container_type; 70 71 public: 72 typedef const Entry* handle_type; 73 insert(const Entry & x)74 handle_type insert(const Entry& x) 75 { 76 return &*cont.insert(x).first; 77 } 78 79 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) insert(Entry && x)80 handle_type insert(Entry&& x) 81 { 82 return &*cont.insert(std::move(x)).first; 83 } 84 #endif 85 erase(handle_type h)86 void erase(handle_type h) 87 { 88 cont.erase(cont.iterator_to(*h)); 89 } 90 entry(handle_type h)91 static const Entry& entry(handle_type h){return *h;} 92 93 private: 94 container_type cont; 95 96 public: 97 typedef hashed_factory_class type; 98 BOOST_MPL_AUX_LAMBDA_SUPPORT( 99 5,hashed_factory_class,(Entry,Key,Hash,Pred,Allocator)) 100 }; 101 102 /* hashed_factory_class specifier */ 103 104 template< 105 typename Hash,typename Pred,typename Allocator 106 BOOST_FLYWEIGHT_NOT_A_PLACEHOLDER_EXPRESSION_DEF 107 > 108 struct hashed_factory:factory_marker 109 { 110 template<typename Entry,typename Key> 111 struct apply: 112 mpl::apply2< 113 hashed_factory_class< 114 boost::mpl::_1,boost::mpl::_2,Hash,Pred,Allocator 115 >, 116 Entry,Key 117 > 118 {}; 119 }; 120 121 } /* namespace flyweights */ 122 123 } /* namespace boost */ 124 125 #endif 126