epoc32/include/stdapis/boost/pending/detail/property.hpp
author William Roberts <williamr@symbian.org>
Wed, 31 Mar 2010 12:33:34 +0100 (2010-03-31)
branchSymbian3
changeset 4 837f303aceeb
parent 3 e1b950c65cb4
permissions -rw-r--r--
Current Symbian^3 public API header files (from PDK 3.0.h)
This is the epoc32/include tree with the "platform" subtrees removed, and
all but a selected few mbg and rsg files removed.
     1 //  (C) Copyright Jeremy Siek 2004 
     2 //  Distributed under the Boost Software License, Version 1.0. (See
     3 //  accompanying file LICENSE_1_0.txt or copy at
     4 //  http://www.boost.org/LICENSE_1_0.txt)
     5 
     6 #ifndef BOOST_DETAIL_PROPERTY_HPP
     7 #define BOOST_DETAIL_PROPERTY_HPP
     8 
     9 #include <utility> // for std::pair
    10 #include <boost/type_traits/same_traits.hpp> // for is_same
    11 
    12 namespace boost {
    13 
    14   namespace detail {
    15 
    16     template <class PropertyTag1, class PropertyTag2>
    17     struct same_property {
    18       enum { value = is_same<PropertyTag1,PropertyTag2>::value };
    19     };
    20 
    21     struct error_property_not_found { };
    22 
    23     template <int TagMatched>
    24     struct property_value_dispatch {
    25       template <class PropertyTag, class T, class Tag>
    26       inline static T& get_value(PropertyTag& p, T*, Tag) {
    27         return p.m_value; 
    28       }
    29       template <class PropertyTag, class T, class Tag>
    30       inline static const T& const_get_value(const PropertyTag& p, T*, Tag) {
    31         return p.m_value; 
    32       }
    33     };
    34 
    35     template <class PropertyList>
    36     struct property_value_end {
    37       template <class T> struct result { typedef T type; };
    38 
    39       template <class T, class Tag>
    40       inline static T& get_value(PropertyList& p, T* t, Tag tag) {
    41         typedef typename PropertyList::next_type Next;
    42         typedef typename Next::tag_type Next_tag;
    43         enum { match = same_property<Next_tag,Tag>::value };
    44         return property_value_dispatch<match>
    45           ::get_value(static_cast<Next&>(p), t, tag);
    46       }
    47       template <class T, class Tag>
    48       inline static const T& const_get_value(const PropertyList& p, T* t, Tag tag) {
    49         typedef typename PropertyList::next_type Next;
    50         typedef typename Next::tag_type Next_tag;
    51         enum { match = same_property<Next_tag,Tag>::value };
    52         return property_value_dispatch<match>
    53           ::const_get_value(static_cast<const Next&>(p), t, tag);
    54       }
    55     };
    56     template <>
    57     struct property_value_end<no_property> {
    58       template <class T> struct result { 
    59         typedef detail::error_property_not_found type; 
    60       };
    61 
    62       // Stop the recursion and return error
    63       template <class T, class Tag>
    64       inline static detail::error_property_not_found&
    65       get_value(no_property&, T*, Tag) {
    66         static error_property_not_found s_prop_not_found;
    67         return s_prop_not_found;
    68       }
    69       template <class T, class Tag>
    70       inline static const detail::error_property_not_found&
    71       const_get_value(const no_property&, T*, Tag) {
    72         static error_property_not_found s_prop_not_found;
    73         return s_prop_not_found;
    74       }
    75     };
    76 
    77     template <>
    78     struct property_value_dispatch<0> {
    79       template <class PropertyList, class T, class Tag>
    80       inline static typename property_value_end<PropertyList>::template result<T>::type&
    81       get_value(PropertyList& p, T* t, Tag tag) {
    82         return property_value_end<PropertyList>::get_value(p, t, tag);
    83       }
    84       template <class PropertyList, class T, class Tag>
    85       inline static const typename property_value_end<PropertyList>::template result<T>::type&
    86       const_get_value(const PropertyList& p, T* t, Tag tag) {
    87         return property_value_end<PropertyList>::const_get_value(p, t, tag);
    88       }
    89     };
    90 
    91     template <class PropertyList>
    92     struct build_property_tag_value_alist
    93     {
    94       typedef typename PropertyList::next_type NextProperty;
    95       typedef typename PropertyList::value_type Value;
    96       typedef typename PropertyList::tag_type Tag;
    97       typedef typename build_property_tag_value_alist<NextProperty>::type Next;
    98       typedef std::pair< std::pair<Tag,Value>, Next> type;
    99     };
   100     template <>
   101     struct build_property_tag_value_alist<no_property>
   102     {
   103       typedef no_property type;
   104     };
   105 
   106 #if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
   107     template <class TagValueAList, class Tag>
   108     struct extract_value {
   109       typedef error_property_not_found type;
   110     };
   111     template <class Value, class Tag1, class Tag2, class Rest>
   112     struct extract_value< std::pair<std::pair<Tag1,Value>,Rest>, Tag2> {
   113       typedef typename extract_value<Rest,Tag2>::type type;
   114     };
   115     template <class Value, class Tag, class Rest>
   116     struct extract_value< std::pair<std::pair<Tag,Value>,Rest>, Tag> {
   117       typedef Value type;
   118     };
   119 #else
   120     // VC++ workaround:
   121     // The main idea here is to replace partial specialization with
   122     // nested template member classes. Of course there is the
   123     // further complication that the outer class of the nested
   124     // template class cannot itself be a template class.
   125     // Hence the need for the ev_selector. -JGS
   126 
   127     struct recursive_extract;
   128     struct end_extract;
   129 
   130     template <class TagValueAList>
   131     struct ev_selector { typedef recursive_extract type; };
   132     template <>
   133     struct ev_selector<no_property> { typedef end_extract type; };
   134 
   135     struct recursive_extract {
   136       template <class TagValueAList, class Tag1>
   137       struct bind_ {
   138         typedef typename TagValueAList::first_type AListFirst;
   139         typedef typename AListFirst::first_type Tag2;
   140         typedef typename AListFirst::second_type Value;
   141         enum { match = same_property<Tag1,Tag2>::value };
   142         typedef typename TagValueAList::second_type Next;
   143         typedef typename ev_selector<Next>::type Extractor;
   144         typedef typename boost::ct_if< match, Value, 
   145           typename Extractor::template bind_<Next,Tag1>::type
   146         >::type type;
   147       };
   148     };
   149     struct end_extract {
   150       template <class AList, class Tag1>
   151       struct bind_ {
   152         typedef error_property_not_found type;
   153       };
   154     };
   155 #endif //!defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
   156 
   157   } // namespace detail 
   158 } // namespace boost
   159 
   160 #endif // BOOST_DETAIL_PROPERTY_HPP