functor_bag.hpp 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. // Boost.Bimap
  2. //
  3. // Copyright (c) 2006-2007 Matias Capeletto
  4. //
  5. // Distributed under the Boost Software License, Version 1.0.
  6. // (See accompanying file LICENSE_1_0.txt or copy at
  7. // http://www.boost.org/LICENSE_1_0.txt)
  8. /// \file container_adaptor/detail/functor_bag.hpp
  9. /// \brief Defines a EBO optimizacion helper for functors.
  10. #ifndef BOOST_BIMAP_CONTAINER_ADAPTOR_DETAIL_FUNCTOR_BAG_HPP
  11. #define BOOST_BIMAP_CONTAINER_ADAPTOR_DETAIL_FUNCTOR_BAG_HPP
  12. #if defined(_MSC_VER)
  13. #pragma once
  14. #endif
  15. #include <boost/config.hpp>
  16. #if defined(BOOST_MSVC)
  17. // This bogus warning will appear when add_const is applied to a
  18. // const volatile reference because we can't detect const volatile
  19. // references with MSVC6.
  20. # pragma warning(push)
  21. # pragma warning(disable:4181)
  22. // warning C4181: qualifier applied to reference type ignored
  23. #endif
  24. #include <boost/mpl/placeholders.hpp>
  25. #include <boost/type_traits/add_reference.hpp>
  26. #include <boost/type_traits/is_base_of.hpp>
  27. #include <boost/mpl/inherit_linearly.hpp>
  28. #include <boost/mpl/inherit.hpp>
  29. namespace boost {
  30. namespace bimaps {
  31. namespace container_adaptor {
  32. namespace detail {
  33. /// \brief EBO optimizacion helper for functors
  34. /**
  35. This class is a generalization of a helper class explained in an article by
  36. Nathan C. Myers.\n
  37. See it at \link http://www.cantrip.org/emptyopt.html
  38. **/
  39. template < class Data, class FunctorList >
  40. struct data_with_functor_bag :
  41. public mpl::inherit_linearly<
  42. FunctorList,
  43. mpl::if_< is_base_of< mpl::_2, mpl::_1 >,
  44. // {
  45. mpl::_1,
  46. // }
  47. // else
  48. // {
  49. mpl::inherit< mpl::_1, mpl::_2 >
  50. // }
  51. >
  52. >::type
  53. {
  54. Data data;
  55. data_with_functor_bag() {}
  56. data_with_functor_bag(BOOST_DEDUCED_TYPENAME add_reference<Data>::type d)
  57. : data(d) {}
  58. template< class Functor >
  59. Functor& functor()
  60. {
  61. return *(static_cast<Functor*>(this));
  62. }
  63. template< class Functor >
  64. const Functor& functor() const
  65. {
  66. return *(static_cast<Functor const *>(this));
  67. }
  68. };
  69. } // namespace detail
  70. } // namespace container_adaptor
  71. } // namespace bimaps
  72. } // namespace boost
  73. #if defined(BOOST_MSVC)
  74. # pragma warning(pop)
  75. #endif
  76. #endif // BOOST_BIMAP_CONTAINER_ADAPTOR_DETAIL_FUNCTOR_BAG_HPP