epoc32/include/stdapis/boost/pending/detail/property.hpp
author William Roberts <williamr@symbian.org>
Wed, 31 Mar 2010 12:27:01 +0100
branchSymbian2
changeset 3 e1b950c65cb4
parent 2 epoc32/include/stdapis/boost/pending/property.hpp@2fe1408b6811
child 4 837f303aceeb
permissions -rw-r--r--
Attempt to represent the S^2->S^3 header reorganisation as a series of "hg rename" operations
     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_PROPERTY_HPP
     7 #define BOOST_PROPERTY_HPP
     8 
     9 #include <boost/pending/ct_if.hpp>
    10 
    11 namespace boost {
    12 
    13   struct no_property { 
    14     typedef no_property tag_type;
    15     typedef no_property next_type;
    16     typedef no_property value_type;
    17     enum { num = 0 };
    18     typedef void kind;
    19   };
    20 
    21   template <class Tag, class T, class Base = no_property>
    22   struct property : public Base {
    23     typedef Base next_type;
    24     typedef Tag tag_type;
    25     typedef T value_type;
    26 #if BOOST_WORKAROUND (__GNUC__, < 3)
    27     property() { }
    28 #else
    29     property() : m_value() { }
    30 #endif
    31     property(const T& v) : m_value(v) { }
    32     property(const T& v, const Base& b) : Base(b), m_value(v) { }
    33     // copy constructor and assignment operator will be generated by compiler
    34 
    35     T m_value;
    36   };
    37 
    38   // The BGL properties specialize property_kind and
    39   // property_num, and use enum's for the Property type (see
    40   // graph/properties.hpp), but the user may want to use a class
    41   // instead with a nested kind type and num.  Also, we may want to
    42   // switch BGL back to using class types for properties at some point.
    43 
    44   template <class PropertyTag>
    45   struct property_kind {
    46     typedef typename PropertyTag::kind type;
    47   };
    48 
    49   template <class P>
    50   struct has_property { 
    51     BOOST_STATIC_CONSTANT(bool, value = true);
    52     typedef true_type type;
    53   };
    54   template <>
    55   struct has_property<no_property> { 
    56     BOOST_STATIC_CONSTANT(bool, value = false); 
    57     typedef false_type type; 
    58   };
    59 
    60 } // namespace boost
    61 
    62 #include <boost/pending/detail/property.hpp>
    63 
    64 namespace boost {
    65 
    66   template <class PropertyList, class Tag>
    67   struct property_value {
    68 #if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
    69     typedef typename detail::build_property_tag_value_alist<PropertyList>::type AList;
    70     typedef typename detail::extract_value<AList,Tag>::type type;
    71 #else
    72     typedef typename detail::build_property_tag_value_alist<PropertyList>::type AList;
    73     typedef typename detail::ev_selector<AList>::type Extractor;
    74     typedef typename Extractor::template bind_<AList,Tag>::type type;
    75 #endif  
    76   };
    77 
    78   template <class Tag1, class Tag2, class T1, class Base>
    79   inline typename property_value<property<Tag1,T1,Base>, Tag2>::type& 
    80   get_property_value(property<Tag1,T1,Base>& p, Tag2 tag2) {
    81     BOOST_STATIC_CONSTANT(bool, 
    82                           match = (detail::same_property<Tag1,Tag2>::value));
    83     typedef property<Tag1,T1,Base> Prop;
    84     typedef typename property_value<Prop, Tag2>::type T2;
    85     T2* t2 = 0;
    86     typedef detail::property_value_dispatch<match> Dispatcher;
    87     return Dispatcher::get_value(p, t2, tag2);
    88   }
    89   template <class Tag1, class Tag2, class T1, class Base>
    90   inline
    91   const typename property_value<property<Tag1,T1,Base>, Tag2>::type& 
    92   get_property_value(const property<Tag1,T1,Base>& p, Tag2 tag2) {
    93     BOOST_STATIC_CONSTANT(bool, 
    94                           match = (detail::same_property<Tag1,Tag2>::value));
    95     typedef property<Tag1,T1,Base> Prop;
    96     typedef typename property_value<Prop, Tag2>::type T2;
    97     T2* t2 = 0;
    98     typedef detail::property_value_dispatch<match> Dispatcher;
    99     return Dispatcher::const_get_value(p, t2, tag2);
   100   }
   101 
   102  namespace detail {
   103 #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
   104    template<typename FinalTag, typename FinalType>
   105    struct retag_property_list
   106    {
   107      typedef property<FinalTag, FinalType> type;
   108      typedef FinalType retagged;
   109    };
   110 
   111    template<typename FinalTag, typename Tag, typename T, typename Base>
   112    struct retag_property_list<FinalTag, property<Tag, T, Base> >
   113    {
   114    private:
   115      typedef retag_property_list<FinalTag, Base> next;
   116 
   117    public:
   118      typedef property<Tag, T, typename next::type> type;
   119      typedef typename next::retagged retagged;
   120    };
   121 
   122    template<typename FinalTag>
   123    struct retag_property_list<FinalTag, no_property>
   124    {
   125      typedef no_property type;
   126      typedef no_property retagged;
   127    };
   128 #endif
   129   }
   130 } // namesapce boost
   131 
   132 #endif /* BOOST_PROPERTY_HPP */