epoc32/include/stdapis/boost/pending/detail/property.hpp
branchSymbian3
changeset 4 837f303aceeb
parent 3 e1b950c65cb4
     1.1 --- a/epoc32/include/stdapis/boost/pending/detail/property.hpp	Wed Mar 31 12:27:01 2010 +0100
     1.2 +++ b/epoc32/include/stdapis/boost/pending/detail/property.hpp	Wed Mar 31 12:33:34 2010 +0100
     1.3 @@ -3,130 +3,158 @@
     1.4  //  accompanying file LICENSE_1_0.txt or copy at
     1.5  //  http://www.boost.org/LICENSE_1_0.txt)
     1.6  
     1.7 -#ifndef BOOST_PROPERTY_HPP
     1.8 -#define BOOST_PROPERTY_HPP
     1.9 +#ifndef BOOST_DETAIL_PROPERTY_HPP
    1.10 +#define BOOST_DETAIL_PROPERTY_HPP
    1.11  
    1.12 -#include <boost/pending/ct_if.hpp>
    1.13 +#include <utility> // for std::pair
    1.14 +#include <boost/type_traits/same_traits.hpp> // for is_same
    1.15  
    1.16  namespace boost {
    1.17  
    1.18 -  struct no_property { 
    1.19 -    typedef no_property tag_type;
    1.20 -    typedef no_property next_type;
    1.21 -    typedef no_property value_type;
    1.22 -    enum { num = 0 };
    1.23 -    typedef void kind;
    1.24 -  };
    1.25 +  namespace detail {
    1.26  
    1.27 -  template <class Tag, class T, class Base = no_property>
    1.28 -  struct property : public Base {
    1.29 -    typedef Base next_type;
    1.30 -    typedef Tag tag_type;
    1.31 -    typedef T value_type;
    1.32 -#if BOOST_WORKAROUND (__GNUC__, < 3)
    1.33 -    property() { }
    1.34 +    template <class PropertyTag1, class PropertyTag2>
    1.35 +    struct same_property {
    1.36 +      enum { value = is_same<PropertyTag1,PropertyTag2>::value };
    1.37 +    };
    1.38 +
    1.39 +    struct error_property_not_found { };
    1.40 +
    1.41 +    template <int TagMatched>
    1.42 +    struct property_value_dispatch {
    1.43 +      template <class PropertyTag, class T, class Tag>
    1.44 +      inline static T& get_value(PropertyTag& p, T*, Tag) {
    1.45 +        return p.m_value; 
    1.46 +      }
    1.47 +      template <class PropertyTag, class T, class Tag>
    1.48 +      inline static const T& const_get_value(const PropertyTag& p, T*, Tag) {
    1.49 +        return p.m_value; 
    1.50 +      }
    1.51 +    };
    1.52 +
    1.53 +    template <class PropertyList>
    1.54 +    struct property_value_end {
    1.55 +      template <class T> struct result { typedef T type; };
    1.56 +
    1.57 +      template <class T, class Tag>
    1.58 +      inline static T& get_value(PropertyList& p, T* t, Tag tag) {
    1.59 +        typedef typename PropertyList::next_type Next;
    1.60 +        typedef typename Next::tag_type Next_tag;
    1.61 +        enum { match = same_property<Next_tag,Tag>::value };
    1.62 +        return property_value_dispatch<match>
    1.63 +          ::get_value(static_cast<Next&>(p), t, tag);
    1.64 +      }
    1.65 +      template <class T, class Tag>
    1.66 +      inline static const T& const_get_value(const PropertyList& p, T* t, Tag tag) {
    1.67 +        typedef typename PropertyList::next_type Next;
    1.68 +        typedef typename Next::tag_type Next_tag;
    1.69 +        enum { match = same_property<Next_tag,Tag>::value };
    1.70 +        return property_value_dispatch<match>
    1.71 +          ::const_get_value(static_cast<const Next&>(p), t, tag);
    1.72 +      }
    1.73 +    };
    1.74 +    template <>
    1.75 +    struct property_value_end<no_property> {
    1.76 +      template <class T> struct result { 
    1.77 +        typedef detail::error_property_not_found type; 
    1.78 +      };
    1.79 +
    1.80 +      // Stop the recursion and return error
    1.81 +      template <class T, class Tag>
    1.82 +      inline static detail::error_property_not_found&
    1.83 +      get_value(no_property&, T*, Tag) {
    1.84 +        static error_property_not_found s_prop_not_found;
    1.85 +        return s_prop_not_found;
    1.86 +      }
    1.87 +      template <class T, class Tag>
    1.88 +      inline static const detail::error_property_not_found&
    1.89 +      const_get_value(const no_property&, T*, Tag) {
    1.90 +        static error_property_not_found s_prop_not_found;
    1.91 +        return s_prop_not_found;
    1.92 +      }
    1.93 +    };
    1.94 +
    1.95 +    template <>
    1.96 +    struct property_value_dispatch<0> {
    1.97 +      template <class PropertyList, class T, class Tag>
    1.98 +      inline static typename property_value_end<PropertyList>::template result<T>::type&
    1.99 +      get_value(PropertyList& p, T* t, Tag tag) {
   1.100 +        return property_value_end<PropertyList>::get_value(p, t, tag);
   1.101 +      }
   1.102 +      template <class PropertyList, class T, class Tag>
   1.103 +      inline static const typename property_value_end<PropertyList>::template result<T>::type&
   1.104 +      const_get_value(const PropertyList& p, T* t, Tag tag) {
   1.105 +        return property_value_end<PropertyList>::const_get_value(p, t, tag);
   1.106 +      }
   1.107 +    };
   1.108 +
   1.109 +    template <class PropertyList>
   1.110 +    struct build_property_tag_value_alist
   1.111 +    {
   1.112 +      typedef typename PropertyList::next_type NextProperty;
   1.113 +      typedef typename PropertyList::value_type Value;
   1.114 +      typedef typename PropertyList::tag_type Tag;
   1.115 +      typedef typename build_property_tag_value_alist<NextProperty>::type Next;
   1.116 +      typedef std::pair< std::pair<Tag,Value>, Next> type;
   1.117 +    };
   1.118 +    template <>
   1.119 +    struct build_property_tag_value_alist<no_property>
   1.120 +    {
   1.121 +      typedef no_property type;
   1.122 +    };
   1.123 +
   1.124 +#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
   1.125 +    template <class TagValueAList, class Tag>
   1.126 +    struct extract_value {
   1.127 +      typedef error_property_not_found type;
   1.128 +    };
   1.129 +    template <class Value, class Tag1, class Tag2, class Rest>
   1.130 +    struct extract_value< std::pair<std::pair<Tag1,Value>,Rest>, Tag2> {
   1.131 +      typedef typename extract_value<Rest,Tag2>::type type;
   1.132 +    };
   1.133 +    template <class Value, class Tag, class Rest>
   1.134 +    struct extract_value< std::pair<std::pair<Tag,Value>,Rest>, Tag> {
   1.135 +      typedef Value type;
   1.136 +    };
   1.137  #else
   1.138 -    property() : m_value() { }
   1.139 -#endif
   1.140 -    property(const T& v) : m_value(v) { }
   1.141 -    property(const T& v, const Base& b) : Base(b), m_value(v) { }
   1.142 -    // copy constructor and assignment operator will be generated by compiler
   1.143 +    // VC++ workaround:
   1.144 +    // The main idea here is to replace partial specialization with
   1.145 +    // nested template member classes. Of course there is the
   1.146 +    // further complication that the outer class of the nested
   1.147 +    // template class cannot itself be a template class.
   1.148 +    // Hence the need for the ev_selector. -JGS
   1.149  
   1.150 -    T m_value;
   1.151 -  };
   1.152 +    struct recursive_extract;
   1.153 +    struct end_extract;
   1.154  
   1.155 -  // The BGL properties specialize property_kind and
   1.156 -  // property_num, and use enum's for the Property type (see
   1.157 -  // graph/properties.hpp), but the user may want to use a class
   1.158 -  // instead with a nested kind type and num.  Also, we may want to
   1.159 -  // switch BGL back to using class types for properties at some point.
   1.160 +    template <class TagValueAList>
   1.161 +    struct ev_selector { typedef recursive_extract type; };
   1.162 +    template <>
   1.163 +    struct ev_selector<no_property> { typedef end_extract type; };
   1.164  
   1.165 -  template <class PropertyTag>
   1.166 -  struct property_kind {
   1.167 -    typedef typename PropertyTag::kind type;
   1.168 -  };
   1.169 +    struct recursive_extract {
   1.170 +      template <class TagValueAList, class Tag1>
   1.171 +      struct bind_ {
   1.172 +        typedef typename TagValueAList::first_type AListFirst;
   1.173 +        typedef typename AListFirst::first_type Tag2;
   1.174 +        typedef typename AListFirst::second_type Value;
   1.175 +        enum { match = same_property<Tag1,Tag2>::value };
   1.176 +        typedef typename TagValueAList::second_type Next;
   1.177 +        typedef typename ev_selector<Next>::type Extractor;
   1.178 +        typedef typename boost::ct_if< match, Value, 
   1.179 +          typename Extractor::template bind_<Next,Tag1>::type
   1.180 +        >::type type;
   1.181 +      };
   1.182 +    };
   1.183 +    struct end_extract {
   1.184 +      template <class AList, class Tag1>
   1.185 +      struct bind_ {
   1.186 +        typedef error_property_not_found type;
   1.187 +      };
   1.188 +    };
   1.189 +#endif //!defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
   1.190  
   1.191 -  template <class P>
   1.192 -  struct has_property { 
   1.193 -    BOOST_STATIC_CONSTANT(bool, value = true);
   1.194 -    typedef true_type type;
   1.195 -  };
   1.196 -  template <>
   1.197 -  struct has_property<no_property> { 
   1.198 -    BOOST_STATIC_CONSTANT(bool, value = false); 
   1.199 -    typedef false_type type; 
   1.200 -  };
   1.201 -
   1.202 +  } // namespace detail 
   1.203  } // namespace boost
   1.204  
   1.205 -#include <boost/pending/detail/property.hpp>
   1.206 -
   1.207 -namespace boost {
   1.208 -
   1.209 -  template <class PropertyList, class Tag>
   1.210 -  struct property_value {
   1.211 -#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
   1.212 -    typedef typename detail::build_property_tag_value_alist<PropertyList>::type AList;
   1.213 -    typedef typename detail::extract_value<AList,Tag>::type type;
   1.214 -#else
   1.215 -    typedef typename detail::build_property_tag_value_alist<PropertyList>::type AList;
   1.216 -    typedef typename detail::ev_selector<AList>::type Extractor;
   1.217 -    typedef typename Extractor::template bind_<AList,Tag>::type type;
   1.218 -#endif  
   1.219 -  };
   1.220 -
   1.221 -  template <class Tag1, class Tag2, class T1, class Base>
   1.222 -  inline typename property_value<property<Tag1,T1,Base>, Tag2>::type& 
   1.223 -  get_property_value(property<Tag1,T1,Base>& p, Tag2 tag2) {
   1.224 -    BOOST_STATIC_CONSTANT(bool, 
   1.225 -                          match = (detail::same_property<Tag1,Tag2>::value));
   1.226 -    typedef property<Tag1,T1,Base> Prop;
   1.227 -    typedef typename property_value<Prop, Tag2>::type T2;
   1.228 -    T2* t2 = 0;
   1.229 -    typedef detail::property_value_dispatch<match> Dispatcher;
   1.230 -    return Dispatcher::get_value(p, t2, tag2);
   1.231 -  }
   1.232 -  template <class Tag1, class Tag2, class T1, class Base>
   1.233 -  inline
   1.234 -  const typename property_value<property<Tag1,T1,Base>, Tag2>::type& 
   1.235 -  get_property_value(const property<Tag1,T1,Base>& p, Tag2 tag2) {
   1.236 -    BOOST_STATIC_CONSTANT(bool, 
   1.237 -                          match = (detail::same_property<Tag1,Tag2>::value));
   1.238 -    typedef property<Tag1,T1,Base> Prop;
   1.239 -    typedef typename property_value<Prop, Tag2>::type T2;
   1.240 -    T2* t2 = 0;
   1.241 -    typedef detail::property_value_dispatch<match> Dispatcher;
   1.242 -    return Dispatcher::const_get_value(p, t2, tag2);
   1.243 -  }
   1.244 -
   1.245 - namespace detail {
   1.246 -#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
   1.247 -   template<typename FinalTag, typename FinalType>
   1.248 -   struct retag_property_list
   1.249 -   {
   1.250 -     typedef property<FinalTag, FinalType> type;
   1.251 -     typedef FinalType retagged;
   1.252 -   };
   1.253 -
   1.254 -   template<typename FinalTag, typename Tag, typename T, typename Base>
   1.255 -   struct retag_property_list<FinalTag, property<Tag, T, Base> >
   1.256 -   {
   1.257 -   private:
   1.258 -     typedef retag_property_list<FinalTag, Base> next;
   1.259 -
   1.260 -   public:
   1.261 -     typedef property<Tag, T, typename next::type> type;
   1.262 -     typedef typename next::retagged retagged;
   1.263 -   };
   1.264 -
   1.265 -   template<typename FinalTag>
   1.266 -   struct retag_property_list<FinalTag, no_property>
   1.267 -   {
   1.268 -     typedef no_property type;
   1.269 -     typedef no_property retagged;
   1.270 -   };
   1.271 -#endif
   1.272 -  }
   1.273 -} // namesapce boost
   1.274 -
   1.275 -#endif /* BOOST_PROPERTY_HPP */
   1.276 +#endif // BOOST_DETAIL_PROPERTY_HPP