1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/ossrv/ossrv_pub/boost_apis/boost/pending/detail/property.hpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,160 @@
1.4 +// (C) Copyright Jeremy Siek 2004
1.5 +// Distributed under the Boost Software License, Version 1.0. (See
1.6 +// accompanying file LICENSE_1_0.txt or copy at
1.7 +// http://www.boost.org/LICENSE_1_0.txt)
1.8 +
1.9 +#ifndef BOOST_DETAIL_PROPERTY_HPP
1.10 +#define BOOST_DETAIL_PROPERTY_HPP
1.11 +
1.12 +#include <utility> // for std::pair
1.13 +#include <boost/type_traits/same_traits.hpp> // for is_same
1.14 +
1.15 +namespace boost {
1.16 +
1.17 + namespace detail {
1.18 +
1.19 + template <class PropertyTag1, class PropertyTag2>
1.20 + struct same_property {
1.21 + enum { value = is_same<PropertyTag1,PropertyTag2>::value };
1.22 + };
1.23 +
1.24 + struct error_property_not_found { };
1.25 +
1.26 + template <int TagMatched>
1.27 + struct property_value_dispatch {
1.28 + template <class PropertyTag, class T, class Tag>
1.29 + inline static T& get_value(PropertyTag& p, T*, Tag) {
1.30 + return p.m_value;
1.31 + }
1.32 + template <class PropertyTag, class T, class Tag>
1.33 + inline static const T& const_get_value(const PropertyTag& p, T*, Tag) {
1.34 + return p.m_value;
1.35 + }
1.36 + };
1.37 +
1.38 + template <class PropertyList>
1.39 + struct property_value_end {
1.40 + template <class T> struct result { typedef T type; };
1.41 +
1.42 + template <class T, class Tag>
1.43 + inline static T& get_value(PropertyList& p, T* t, Tag tag) {
1.44 + typedef typename PropertyList::next_type Next;
1.45 + typedef typename Next::tag_type Next_tag;
1.46 + enum { match = same_property<Next_tag,Tag>::value };
1.47 + return property_value_dispatch<match>
1.48 + ::get_value(static_cast<Next&>(p), t, tag);
1.49 + }
1.50 + template <class T, class Tag>
1.51 + inline static const T& const_get_value(const PropertyList& p, T* t, Tag tag) {
1.52 + typedef typename PropertyList::next_type Next;
1.53 + typedef typename Next::tag_type Next_tag;
1.54 + enum { match = same_property<Next_tag,Tag>::value };
1.55 + return property_value_dispatch<match>
1.56 + ::const_get_value(static_cast<const Next&>(p), t, tag);
1.57 + }
1.58 + };
1.59 + template <>
1.60 + struct property_value_end<no_property> {
1.61 + template <class T> struct result {
1.62 + typedef detail::error_property_not_found type;
1.63 + };
1.64 +
1.65 + // Stop the recursion and return error
1.66 + template <class T, class Tag>
1.67 + inline static detail::error_property_not_found&
1.68 + get_value(no_property&, T*, Tag) {
1.69 + static error_property_not_found s_prop_not_found;
1.70 + return s_prop_not_found;
1.71 + }
1.72 + template <class T, class Tag>
1.73 + inline static const detail::error_property_not_found&
1.74 + const_get_value(const no_property&, T*, Tag) {
1.75 + static error_property_not_found s_prop_not_found;
1.76 + return s_prop_not_found;
1.77 + }
1.78 + };
1.79 +
1.80 + template <>
1.81 + struct property_value_dispatch<0> {
1.82 + template <class PropertyList, class T, class Tag>
1.83 + inline static typename property_value_end<PropertyList>::template result<T>::type&
1.84 + get_value(PropertyList& p, T* t, Tag tag) {
1.85 + return property_value_end<PropertyList>::get_value(p, t, tag);
1.86 + }
1.87 + template <class PropertyList, class T, class Tag>
1.88 + inline static const typename property_value_end<PropertyList>::template result<T>::type&
1.89 + const_get_value(const PropertyList& p, T* t, Tag tag) {
1.90 + return property_value_end<PropertyList>::const_get_value(p, t, tag);
1.91 + }
1.92 + };
1.93 +
1.94 + template <class PropertyList>
1.95 + struct build_property_tag_value_alist
1.96 + {
1.97 + typedef typename PropertyList::next_type NextProperty;
1.98 + typedef typename PropertyList::value_type Value;
1.99 + typedef typename PropertyList::tag_type Tag;
1.100 + typedef typename build_property_tag_value_alist<NextProperty>::type Next;
1.101 + typedef std::pair< std::pair<Tag,Value>, Next> type;
1.102 + };
1.103 + template <>
1.104 + struct build_property_tag_value_alist<no_property>
1.105 + {
1.106 + typedef no_property type;
1.107 + };
1.108 +
1.109 +#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
1.110 + template <class TagValueAList, class Tag>
1.111 + struct extract_value {
1.112 + typedef error_property_not_found type;
1.113 + };
1.114 + template <class Value, class Tag1, class Tag2, class Rest>
1.115 + struct extract_value< std::pair<std::pair<Tag1,Value>,Rest>, Tag2> {
1.116 + typedef typename extract_value<Rest,Tag2>::type type;
1.117 + };
1.118 + template <class Value, class Tag, class Rest>
1.119 + struct extract_value< std::pair<std::pair<Tag,Value>,Rest>, Tag> {
1.120 + typedef Value type;
1.121 + };
1.122 +#else
1.123 + // VC++ workaround:
1.124 + // The main idea here is to replace partial specialization with
1.125 + // nested template member classes. Of course there is the
1.126 + // further complication that the outer class of the nested
1.127 + // template class cannot itself be a template class.
1.128 + // Hence the need for the ev_selector. -JGS
1.129 +
1.130 + struct recursive_extract;
1.131 + struct end_extract;
1.132 +
1.133 + template <class TagValueAList>
1.134 + struct ev_selector { typedef recursive_extract type; };
1.135 + template <>
1.136 + struct ev_selector<no_property> { typedef end_extract type; };
1.137 +
1.138 + struct recursive_extract {
1.139 + template <class TagValueAList, class Tag1>
1.140 + struct bind_ {
1.141 + typedef typename TagValueAList::first_type AListFirst;
1.142 + typedef typename AListFirst::first_type Tag2;
1.143 + typedef typename AListFirst::second_type Value;
1.144 + enum { match = same_property<Tag1,Tag2>::value };
1.145 + typedef typename TagValueAList::second_type Next;
1.146 + typedef typename ev_selector<Next>::type Extractor;
1.147 + typedef typename boost::ct_if< match, Value,
1.148 + typename Extractor::template bind_<Next,Tag1>::type
1.149 + >::type type;
1.150 + };
1.151 + };
1.152 + struct end_extract {
1.153 + template <class AList, class Tag1>
1.154 + struct bind_ {
1.155 + typedef error_property_not_found type;
1.156 + };
1.157 + };
1.158 +#endif //!defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
1.159 +
1.160 + } // namespace detail
1.161 +} // namespace boost
1.162 +
1.163 +#endif // BOOST_DETAIL_PROPERTY_HPP