diff -r e1b950c65cb4 -r 837f303aceeb epoc32/include/stdapis/boost/pending/detail/property.hpp --- a/epoc32/include/stdapis/boost/pending/detail/property.hpp Wed Mar 31 12:27:01 2010 +0100 +++ b/epoc32/include/stdapis/boost/pending/detail/property.hpp Wed Mar 31 12:33:34 2010 +0100 @@ -3,130 +3,158 @@ // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#ifndef BOOST_PROPERTY_HPP -#define BOOST_PROPERTY_HPP +#ifndef BOOST_DETAIL_PROPERTY_HPP +#define BOOST_DETAIL_PROPERTY_HPP -#include +#include // for std::pair +#include // for is_same namespace boost { - struct no_property { - typedef no_property tag_type; - typedef no_property next_type; - typedef no_property value_type; - enum { num = 0 }; - typedef void kind; - }; + namespace detail { - template - struct property : public Base { - typedef Base next_type; - typedef Tag tag_type; - typedef T value_type; -#if BOOST_WORKAROUND (__GNUC__, < 3) - property() { } + template + struct same_property { + enum { value = is_same::value }; + }; + + struct error_property_not_found { }; + + template + struct property_value_dispatch { + template + inline static T& get_value(PropertyTag& p, T*, Tag) { + return p.m_value; + } + template + inline static const T& const_get_value(const PropertyTag& p, T*, Tag) { + return p.m_value; + } + }; + + template + struct property_value_end { + template struct result { typedef T type; }; + + template + inline static T& get_value(PropertyList& p, T* t, Tag tag) { + typedef typename PropertyList::next_type Next; + typedef typename Next::tag_type Next_tag; + enum { match = same_property::value }; + return property_value_dispatch + ::get_value(static_cast(p), t, tag); + } + template + inline static const T& const_get_value(const PropertyList& p, T* t, Tag tag) { + typedef typename PropertyList::next_type Next; + typedef typename Next::tag_type Next_tag; + enum { match = same_property::value }; + return property_value_dispatch + ::const_get_value(static_cast(p), t, tag); + } + }; + template <> + struct property_value_end { + template struct result { + typedef detail::error_property_not_found type; + }; + + // Stop the recursion and return error + template + inline static detail::error_property_not_found& + get_value(no_property&, T*, Tag) { + static error_property_not_found s_prop_not_found; + return s_prop_not_found; + } + template + inline static const detail::error_property_not_found& + const_get_value(const no_property&, T*, Tag) { + static error_property_not_found s_prop_not_found; + return s_prop_not_found; + } + }; + + template <> + struct property_value_dispatch<0> { + template + inline static typename property_value_end::template result::type& + get_value(PropertyList& p, T* t, Tag tag) { + return property_value_end::get_value(p, t, tag); + } + template + inline static const typename property_value_end::template result::type& + const_get_value(const PropertyList& p, T* t, Tag tag) { + return property_value_end::const_get_value(p, t, tag); + } + }; + + template + struct build_property_tag_value_alist + { + typedef typename PropertyList::next_type NextProperty; + typedef typename PropertyList::value_type Value; + typedef typename PropertyList::tag_type Tag; + typedef typename build_property_tag_value_alist::type Next; + typedef std::pair< std::pair, Next> type; + }; + template <> + struct build_property_tag_value_alist + { + typedef no_property type; + }; + +#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + template + struct extract_value { + typedef error_property_not_found type; + }; + template + struct extract_value< std::pair,Rest>, Tag2> { + typedef typename extract_value::type type; + }; + template + struct extract_value< std::pair,Rest>, Tag> { + typedef Value type; + }; #else - property() : m_value() { } -#endif - property(const T& v) : m_value(v) { } - property(const T& v, const Base& b) : Base(b), m_value(v) { } - // copy constructor and assignment operator will be generated by compiler + // VC++ workaround: + // The main idea here is to replace partial specialization with + // nested template member classes. Of course there is the + // further complication that the outer class of the nested + // template class cannot itself be a template class. + // Hence the need for the ev_selector. -JGS - T m_value; - }; + struct recursive_extract; + struct end_extract; - // The BGL properties specialize property_kind and - // property_num, and use enum's for the Property type (see - // graph/properties.hpp), but the user may want to use a class - // instead with a nested kind type and num. Also, we may want to - // switch BGL back to using class types for properties at some point. + template + struct ev_selector { typedef recursive_extract type; }; + template <> + struct ev_selector { typedef end_extract type; }; - template - struct property_kind { - typedef typename PropertyTag::kind type; - }; + struct recursive_extract { + template + struct bind_ { + typedef typename TagValueAList::first_type AListFirst; + typedef typename AListFirst::first_type Tag2; + typedef typename AListFirst::second_type Value; + enum { match = same_property::value }; + typedef typename TagValueAList::second_type Next; + typedef typename ev_selector::type Extractor; + typedef typename boost::ct_if< match, Value, + typename Extractor::template bind_::type + >::type type; + }; + }; + struct end_extract { + template + struct bind_ { + typedef error_property_not_found type; + }; + }; +#endif //!defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - template - struct has_property { - BOOST_STATIC_CONSTANT(bool, value = true); - typedef true_type type; - }; - template <> - struct has_property { - BOOST_STATIC_CONSTANT(bool, value = false); - typedef false_type type; - }; - + } // namespace detail } // namespace boost -#include - -namespace boost { - - template - struct property_value { -#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - typedef typename detail::build_property_tag_value_alist::type AList; - typedef typename detail::extract_value::type type; -#else - typedef typename detail::build_property_tag_value_alist::type AList; - typedef typename detail::ev_selector::type Extractor; - typedef typename Extractor::template bind_::type type; -#endif - }; - - template - inline typename property_value, Tag2>::type& - get_property_value(property& p, Tag2 tag2) { - BOOST_STATIC_CONSTANT(bool, - match = (detail::same_property::value)); - typedef property Prop; - typedef typename property_value::type T2; - T2* t2 = 0; - typedef detail::property_value_dispatch Dispatcher; - return Dispatcher::get_value(p, t2, tag2); - } - template - inline - const typename property_value, Tag2>::type& - get_property_value(const property& p, Tag2 tag2) { - BOOST_STATIC_CONSTANT(bool, - match = (detail::same_property::value)); - typedef property Prop; - typedef typename property_value::type T2; - T2* t2 = 0; - typedef detail::property_value_dispatch Dispatcher; - return Dispatcher::const_get_value(p, t2, tag2); - } - - namespace detail { -#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) - template - struct retag_property_list - { - typedef property type; - typedef FinalType retagged; - }; - - template - struct retag_property_list > - { - private: - typedef retag_property_list next; - - public: - typedef property type; - typedef typename next::retagged retagged; - }; - - template - struct retag_property_list - { - typedef no_property type; - typedef no_property retagged; - }; -#endif - } -} // namesapce boost - -#endif /* BOOST_PROPERTY_HPP */ +#endif // BOOST_DETAIL_PROPERTY_HPP