assoc_container_factory.hpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. /* Copyright 2006-2015 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. #ifndef BOOST_FLYWEIGHT_ASSOC_CONTAINER_FACTORY_HPP
  9. #define BOOST_FLYWEIGHT_ASSOC_CONTAINER_FACTORY_HPP
  10. #if defined(_MSC_VER)
  11. #pragma once
  12. #endif
  13. #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
  14. #include <boost/flyweight/assoc_container_factory_fwd.hpp>
  15. #include <boost/flyweight/detail/is_placeholder_expr.hpp>
  16. #include <boost/flyweight/detail/nested_xxx_if_not_ph.hpp>
  17. #include <boost/flyweight/factory_tag.hpp>
  18. #include <boost/mpl/apply.hpp>
  19. #include <boost/mpl/aux_/lambda_support.hpp>
  20. #include <boost/mpl/if.hpp>
  21. #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
  22. #include <utility>
  23. #endif
  24. namespace boost{namespace flyweights{namespace detail{
  25. BOOST_FLYWEIGHT_NESTED_XXX_IF_NOT_PLACEHOLDER_EXPRESSION_DEF(iterator)
  26. BOOST_FLYWEIGHT_NESTED_XXX_IF_NOT_PLACEHOLDER_EXPRESSION_DEF(value_type)
  27. }}} /* namespace boost::flyweights::detail */
  28. /* Factory class using a given associative container.
  29. */
  30. namespace boost{
  31. namespace flyweights{
  32. template<typename Container>
  33. class assoc_container_factory_class:public factory_marker
  34. {
  35. public:
  36. /* When assoc_container_factory_class<Container> is an MPL placeholder
  37. * expression, referring to Container::iterator and Container::value_type
  38. * force the MPL placeholder expression Container to be instantiated, which
  39. * is wasteful and can fail in concept-checked STL implementations.
  40. * We protect ourselves against this circumstance.
  41. */
  42. typedef typename detail::nested_iterator_if_not_placeholder_expression<
  43. Container
  44. >::type handle_type;
  45. typedef typename detail::nested_value_type_if_not_placeholder_expression<
  46. Container
  47. >::type entry_type;
  48. handle_type insert(const entry_type& x)
  49. {
  50. return cont.insert(x).first;
  51. }
  52. #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
  53. handle_type insert(entry_type&& x)
  54. {
  55. return cont.insert(std::move(x)).first;
  56. }
  57. #endif
  58. void erase(handle_type h)
  59. {
  60. cont.erase(h);
  61. }
  62. static const entry_type& entry(handle_type h){return *h;}
  63. private:
  64. /* As above, avoid instantiating Container if it is an
  65. * MPL placeholder expression.
  66. */
  67. typedef typename mpl::if_<
  68. detail::is_placeholder_expression<Container>,
  69. int,
  70. Container
  71. >::type container_type;
  72. container_type cont;
  73. public:
  74. typedef assoc_container_factory_class type;
  75. BOOST_MPL_AUX_LAMBDA_SUPPORT(1,assoc_container_factory_class,(Container))
  76. };
  77. /* assoc_container_factory_class specifier */
  78. template<
  79. typename ContainerSpecifier
  80. BOOST_FLYWEIGHT_NOT_A_PLACEHOLDER_EXPRESSION_DEF
  81. >
  82. struct assoc_container_factory:factory_marker
  83. {
  84. template<typename Entry,typename Key>
  85. struct apply
  86. {
  87. typedef assoc_container_factory_class<
  88. typename mpl::apply2<ContainerSpecifier,Entry,Key>::type
  89. > type;
  90. };
  91. };
  92. } /* namespace flyweights */
  93. } /* namespace boost */
  94. #endif