LCOV - code coverage report
Current view: top level - usr/include/boost/multi_index - member.hpp (source / functions) Hit Total Coverage
Test: ROSE Lines: 0 4 0.0 %
Date: 2022-12-08 13:48:47 Functions: 0 0 -
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* Copyright 2003-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/multi_index for library home page.
       7             :  */
       8             : 
       9             : #ifndef BOOST_MULTI_INDEX_MEMBER_HPP
      10             : #define BOOST_MULTI_INDEX_MEMBER_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/mpl/if.hpp>
      18             : #include <boost/type_traits/is_const.hpp>
      19             : #include <boost/utility/enable_if.hpp>
      20             : #include <cstddef>
      21             : 
      22             : #if !defined(BOOST_NO_SFINAE)
      23             : #include <boost/type_traits/is_convertible.hpp>
      24             : #endif
      25             : 
      26             : namespace boost{
      27             : 
      28             : template<class T> class reference_wrapper; /* fwd decl. */
      29             : 
      30             : namespace multi_index{
      31             : 
      32             : namespace detail{
      33             : 
      34             : /* member is a read/write key extractor for accessing a given
      35             :  * member of a class.
      36             :  * Additionally, member is overloaded to support referece_wrappers
      37             :  * of T and "chained pointers" to T's. By chained pointer to T we mean
      38             :  * a type P  such that, given a p of Type P
      39             :  *   *...n...*x is convertible to T&, for some n>=1.
      40             :  * Examples of chained pointers are raw and smart pointers, iterators and
      41             :  * arbitrary combinations of these (vg. T** or unique_ptr<T*>.)
      42             :  */
      43             : 
      44             : template<class Class,typename Type,Type Class::*PtrToMember>
      45             : struct const_member_base
      46             : {
      47             :   typedef Type result_type;
      48             : 
      49             :   template<typename ChainedPtr>
      50             : 
      51             : #if !defined(BOOST_NO_SFINAE)
      52             :   typename disable_if<
      53             :     is_convertible<const ChainedPtr&,const Class&>,Type&>::type
      54             : #else
      55             :   Type&
      56             : #endif
      57             :   
      58             :   operator()(const ChainedPtr& x)const
      59             :   {
      60             :     return operator()(*x);
      61             :   }
      62             : 
      63             :   Type& operator()(const Class& x)const
      64             :   {
      65             :     return x.*PtrToMember;
      66             :   }
      67             : 
      68             :   Type& operator()(const reference_wrapper<const Class>& x)const
      69             :   {
      70             :     return operator()(x.get());
      71             :   }
      72             : 
      73             :   Type& operator()(const reference_wrapper<Class>& x)const
      74             :   { 
      75             :     return operator()(x.get());
      76             :   }
      77             : };
      78             : 
      79             : template<class Class,typename Type,Type Class::*PtrToMember>
      80             : struct non_const_member_base
      81             : {
      82             :   typedef Type result_type;
      83             : 
      84             :   template<typename ChainedPtr>
      85             : 
      86             : #if !defined(BOOST_NO_SFINAE)
      87             :   typename disable_if<
      88             :     is_convertible<const ChainedPtr&,const Class&>,Type&>::type
      89             : #else
      90             :   Type&
      91             : #endif
      92             : 
      93             :   operator()(const ChainedPtr& x)const
      94             :   {
      95             :     return operator()(*x);
      96             :   }
      97             : 
      98           0 :   const Type& operator()(const Class& x)const
      99             :   {
     100           0 :     return x.*PtrToMember;
     101             :   }
     102             : 
     103           0 :   Type& operator()(Class& x)const
     104             :   { 
     105           0 :     return x.*PtrToMember;
     106             :   }
     107             : 
     108             :   const Type& operator()(const reference_wrapper<const Class>& x)const
     109             :   {
     110             :     return operator()(x.get());
     111             :   }
     112             : 
     113             :   Type& operator()(const reference_wrapper<Class>& x)const
     114             :   { 
     115             :     return operator()(x.get());
     116             :   }
     117             : };
     118             : 
     119             : } /* namespace multi_index::detail */
     120             : 
     121             : template<class Class,typename Type,Type Class::*PtrToMember>
     122             : struct member:
     123             :   mpl::if_c<
     124             :     is_const<Type>::value,
     125             :     detail::const_member_base<Class,Type,PtrToMember>,
     126             :     detail::non_const_member_base<Class,Type,PtrToMember>
     127             :   >::type
     128             : {
     129             : };
     130             : 
     131             : namespace detail{
     132             : 
     133             : /* MSVC++ 6.0 does not support properly pointers to members as
     134             :  * non-type template arguments, as reported in
     135             :  *   http://support.microsoft.com/default.aspx?scid=kb;EN-US;249045
     136             :  * A similar problem (though not identical) is shown by MSVC++ 7.0.
     137             :  * We provide an alternative to member<> accepting offsets instead
     138             :  * of pointers to members. This happens to work even for non-POD
     139             :  * types (although the standard forbids use of offsetof on these),
     140             :  * so it serves as a workaround in this compiler for all practical
     141             :  * purposes.
     142             :  * Surprisingly enough, other compilers, like Intel C++ 7.0/7.1 and
     143             :  * Visual Age 6.0, have similar bugs. This replacement of member<>
     144             :  * can be used for them too.
     145             :  *
     146             :  * Support for such old compilers is dropped and
     147             :  * [non_]const_member_offset_base is deprecated.
     148             :  */
     149             : 
     150             : template<class Class,typename Type,std::size_t OffsetOfMember>
     151             : struct const_member_offset_base
     152             : {
     153             :   typedef Type result_type;
     154             : 
     155             :   template<typename ChainedPtr>
     156             : 
     157             : #if !defined(BOOST_NO_SFINAE)
     158             :   typename disable_if<
     159             :     is_convertible<const ChainedPtr&,const Class&>,Type&>::type
     160             : #else
     161             :   Type&
     162             : #endif 
     163             :     
     164             :   operator()(const ChainedPtr& x)const
     165             :   {
     166             :     return operator()(*x);
     167             :   }
     168             : 
     169             :   Type& operator()(const Class& x)const
     170             :   {
     171             :     return *static_cast<const Type*>(
     172             :       static_cast<const void*>(
     173             :         static_cast<const char*>(
     174             :           static_cast<const void *>(&x))+OffsetOfMember));
     175             :   }
     176             : 
     177             :   Type& operator()(const reference_wrapper<const Class>& x)const
     178             :   {
     179             :     return operator()(x.get());
     180             :   }
     181             : 
     182             :   Type& operator()(const reference_wrapper<Class>& x)const
     183             :   {
     184             :     return operator()(x.get());
     185             :   }
     186             : };
     187             : 
     188             : template<class Class,typename Type,std::size_t OffsetOfMember>
     189             : struct non_const_member_offset_base
     190             : {
     191             :   typedef Type result_type;
     192             : 
     193             :   template<typename ChainedPtr>
     194             : 
     195             : #if !defined(BOOST_NO_SFINAE)
     196             :   typename disable_if<
     197             :     is_convertible<const ChainedPtr&,const Class&>,Type&>::type
     198             : #else
     199             :   Type&
     200             : #endif 
     201             :   
     202             :   operator()(const ChainedPtr& x)const
     203             :   {
     204             :     return operator()(*x);
     205             :   }
     206             : 
     207             :   const Type& operator()(const Class& x)const
     208             :   {
     209             :     return *static_cast<const Type*>(
     210             :       static_cast<const void*>(
     211             :         static_cast<const char*>(
     212             :           static_cast<const void *>(&x))+OffsetOfMember));
     213             :   }
     214             : 
     215             :   Type& operator()(Class& x)const
     216             :   { 
     217             :     return *static_cast<Type*>(
     218             :       static_cast<void*>(
     219             :         static_cast<char*>(static_cast<void *>(&x))+OffsetOfMember));
     220             :   }
     221             : 
     222             :   const Type& operator()(const reference_wrapper<const Class>& x)const
     223             :   {
     224             :     return operator()(x.get());
     225             :   }
     226             : 
     227             :   Type& operator()(const reference_wrapper<Class>& x)const
     228             :   {
     229             :     return operator()(x.get());
     230             :   }
     231             : };
     232             : 
     233             : } /* namespace multi_index::detail */
     234             : 
     235             : template<class Class,typename Type,std::size_t OffsetOfMember>
     236             : struct member_offset:
     237             :   mpl::if_c<
     238             :     is_const<Type>::value,
     239             :     detail::const_member_offset_base<Class,Type,OffsetOfMember>,
     240             :     detail::non_const_member_offset_base<Class,Type,OffsetOfMember>
     241             :   >::type
     242             : {
     243             : };
     244             : 
     245             : /* BOOST_MULTI_INDEX_MEMBER resolves to member in the normal cases,
     246             :  * and to member_offset as a workaround in those defective compilers for
     247             :  * which BOOST_NO_POINTER_TO_MEMBER_TEMPLATE_PARAMETERS is defined.
     248             :  */
     249             : 
     250             : #if defined(BOOST_NO_POINTER_TO_MEMBER_TEMPLATE_PARAMETERS)
     251             : #define BOOST_MULTI_INDEX_MEMBER(Class,Type,MemberName) \
     252             : ::boost::multi_index::member_offset< Class,Type,offsetof(Class,MemberName) >
     253             : #else
     254             : #define BOOST_MULTI_INDEX_MEMBER(Class,Type,MemberName) \
     255             : ::boost::multi_index::member< Class,Type,&Class::MemberName >
     256             : #endif
     257             : 
     258             : } /* namespace multi_index */
     259             : 
     260             : } /* namespace boost */
     261             : 
     262             : #endif

Generated by: LCOV version 1.14