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 
9 /// \file container_adaptor/detail/functor_bag.hpp
10 /// \brief Defines a EBO optimizacion helper for functors.
11 
12 #ifndef BOOST_BIMAP_CONTAINER_ADAPTOR_DETAIL_FUNCTOR_BAG_HPP
13 #define BOOST_BIMAP_CONTAINER_ADAPTOR_DETAIL_FUNCTOR_BAG_HPP
14 
15 #if defined(_MSC_VER)
16 #pragma once
17 #endif
18 
19 #include <boost/config.hpp>
20 
21 #if defined(BOOST_MSVC)
22 // This bogus warning will appear when add_const is applied to a
23 // const volatile reference because we can't detect const volatile
24 // references with MSVC6.
25 #   pragma warning(push)
26 #   pragma warning(disable:4181)
27 // warning C4181: qualifier applied to reference type ignored
28 #endif
29 
30 #include <boost/mpl/placeholders.hpp>
31 
32 #include <boost/type_traits/add_reference.hpp>
33 #include <boost/type_traits/is_base_of.hpp>
34 
35 #include <boost/mpl/inherit_linearly.hpp>
36 #include <boost/mpl/inherit.hpp>
37 
38 namespace boost {
39 namespace bimaps {
40 namespace container_adaptor {
41 namespace detail {
42 
43 /// \brief EBO optimizacion helper for functors
44 /**
45 
46 This class is a generalization of a helper class explained in an article by
47 Nathan C. Myers.\n
48 See it at \link http://www.cantrip.org/emptyopt.html
49                                                                                     **/
50 
51 template < class Data, class FunctorList >
52 struct data_with_functor_bag :
53 
54     public mpl::inherit_linearly<
55 
56         FunctorList,
57         mpl::if_< is_base_of< mpl::_2, mpl::_1 >,
58         //   {
59                  mpl::_1,
60         //   }
61         //   else
62         //   {
63                  mpl::inherit< mpl::_1, mpl::_2 >
64         //   }
65         >
66 
67     >::type
68 {
69     Data data;
70 
data_with_functor_bagboost::bimaps::container_adaptor::detail::data_with_functor_bag71     data_with_functor_bag() {}
72 
data_with_functor_bagboost::bimaps::container_adaptor::detail::data_with_functor_bag73     data_with_functor_bag(BOOST_DEDUCED_TYPENAME add_reference<Data>::type d)
74         : data(d) {}
75 
76     template< class Functor >
functorboost::bimaps::container_adaptor::detail::data_with_functor_bag77     Functor& functor()
78     {
79         return *(static_cast<Functor*>(this));
80     }
81 
82     template< class Functor >
functorboost::bimaps::container_adaptor::detail::data_with_functor_bag83     const Functor& functor() const
84     {
85         return *(static_cast<Functor const *>(this));
86     }
87 };
88 
89 } // namespace detail
90 } // namespace container_adaptor
91 } // namespace bimaps
92 } // namespace boost
93 
94 #if defined(BOOST_MSVC)
95 #   pragma warning(pop)
96 #endif
97 
98 #endif // BOOST_BIMAP_CONTAINER_ADAPTOR_DETAIL_FUNCTOR_BAG_HPP
99 
100 
101