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