Chris@16: #ifndef BOOST_RANGE_DETAIL_MICROSOFT_HPP Chris@16: #define BOOST_RANGE_DETAIL_MICROSOFT_HPP Chris@16: Chris@16: // Boost.Range MFC/ATL Extension Chris@16: // Chris@16: // Copyright Shunsuke Sogame 2005-2006. Chris@16: // Distributed under the Boost Software License, Version 1.0. Chris@16: // (See accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: Chris@16: Chris@16: Chris@16: // config Chris@16: // Chris@16: Chris@16: Chris@16: #include Chris@16: Chris@16: Chris@16: #define BOOST_RANGE_DETAIL_MICROSOFT_RANGE_VERSION_1 1 Chris@16: Chris@16: Chris@16: #if !defined(BOOST_RANGE_DETAIL_MICROSOFT_RANGE_VERSION_1) Chris@16: #define BOOST_RANGE_DETAIL_MICROSOFT_range_mutable_iterator range_mutable_iterator Chris@16: #define BOOST_RANGE_DETAIL_MICROSOFT_range_begin range_begin Chris@16: #define BOOST_RANGE_DETAIL_MICROSOFT_range_end range_end Chris@16: #else Chris@16: #define BOOST_RANGE_DETAIL_MICROSOFT_range_mutable_iterator range_mutable_iterator Chris@16: #define BOOST_RANGE_DETAIL_MICROSOFT_range_begin range_begin Chris@16: #define BOOST_RANGE_DETAIL_MICROSOFT_range_end range_end Chris@16: #endif Chris@16: Chris@16: Chris@16: Chris@16: Chris@16: // yet another customization way Chris@16: // Chris@16: Chris@16: Chris@16: #include // iterator_difference Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include // disable_if Chris@16: Chris@16: #if !defined(BOOST_RANGE_DETAIL_MICROSOFT_RANGE_VERSION_1) Chris@16: #include Chris@16: #else Chris@16: #include // distance Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #endif Chris@16: Chris@16: Chris@16: namespace boost { namespace range_detail_microsoft { Chris@16: Chris@16: Chris@16: // customization point Chris@16: // Chris@16: Chris@16: template< class Tag > Chris@16: struct customization; Chris@16: Chris@16: Chris@16: template< class T > Chris@16: struct customization_tag; Chris@16: Chris@16: Chris@16: struct using_type_as_tag Chris@16: { }; Chris@16: Chris@16: Chris@16: // Topic: Chris@16: // In fact, it is unnecessary for VC++. Chris@16: // VC++'s behavior seems conforming, while GCC fails without this. Chris@16: template< class Iterator, class T > Chris@16: struct mutable_ : Chris@16: disable_if< is_const, Iterator > Chris@16: { }; Chris@16: Chris@16: Chris@16: // helpers Chris@16: // Chris@16: Chris@16: template< class Tag, class T > Chris@16: struct customization_tag_of Chris@16: { Chris@16: typedef typename mpl::if_< is_same, Chris@16: T, Chris@16: Tag Chris@16: >::type type; Chris@16: }; Chris@16: Chris@16: Chris@16: template< class T > Chris@16: struct customization_of Chris@16: { Chris@16: typedef typename remove_cv::type bare_t; Chris@16: typedef typename customization_tag::type tag_t; Chris@16: typedef customization type; Chris@16: }; Chris@16: Chris@16: Chris@16: template< class T > Chris@16: struct mutable_iterator_of Chris@16: { Chris@16: typedef typename remove_cv::type bare_t; Chris@16: typedef typename customization_of::type cust_t; Chris@16: typedef typename cust_t::template meta::mutable_iterator type; Chris@16: }; Chris@16: Chris@16: Chris@16: template< class T > Chris@16: struct const_iterator_of Chris@16: { Chris@16: typedef typename remove_cv::type bare_t; Chris@16: typedef typename customization_of::type cust_t; Chris@16: typedef typename cust_t::template meta::const_iterator type; Chris@16: }; Chris@16: Chris@16: Chris@16: template< class T > Chris@16: struct size_type_of Chris@16: { Chris@16: typedef typename range_detail_microsoft::mutable_iterator_of::type miter_t; Chris@16: typedef typename iterator_difference::type type; Chris@16: }; Chris@16: Chris@16: Chris@16: template< class T > inline Chris@16: typename mutable_iterator_of::type Chris@16: begin_of(T& x) Chris@16: { Chris@16: typedef typename customization_of::type cust_t; Chris@16: return cust_t().template begin::type>(x); Chris@16: } Chris@16: Chris@16: Chris@16: template< class T > inline Chris@16: typename const_iterator_of::type Chris@16: begin_of(T const& x) Chris@16: { Chris@16: typedef typename customization_of::type cust_t; Chris@16: return cust_t().template begin::type>(x); Chris@16: } Chris@16: Chris@16: Chris@16: template< class T > inline Chris@16: typename mutable_iterator_of::type Chris@16: end_of(T& x) Chris@16: { Chris@16: typedef typename customization_of::type cust_t; Chris@16: return cust_t().template end::type>(x); Chris@16: } Chris@16: Chris@16: Chris@16: template< class T > inline Chris@16: typename const_iterator_of::type Chris@16: end_of(T const& x) Chris@16: { Chris@16: typedef typename customization_of::type cust_t; Chris@16: return cust_t().template end::type>(x); Chris@16: } Chris@16: Chris@16: Chris@16: #if defined(BOOST_RANGE_DETAIL_MICROSOFT_RANGE_VERSION_1) Chris@16: Chris@16: template< class T > inline Chris@16: typename size_type_of::type Chris@16: size_of(T const& x) Chris@16: { Chris@16: return std::distance(boost::begin(x), boost::end(x)); Chris@16: } Chris@16: Chris@16: #endif Chris@16: Chris@16: Chris@16: template< class Range > Chris@16: struct compatible_mutable_iterator : Chris@16: BOOST_RANGE_DETAIL_MICROSOFT_range_mutable_iterator Chris@16: { }; Chris@16: Chris@16: Chris@16: } } // namespace boost::range_detail_microsoft Chris@16: Chris@16: Chris@16: #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_open(NamespaceList) \ Chris@16: BOOST_PP_LIST_FOR_EACH(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_open_op, ~, NamespaceList) \ Chris@16: /**/ Chris@16: Chris@16: #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_open_op(r, data, elem) \ Chris@16: namespace elem { \ Chris@16: /**/ Chris@16: Chris@16: Chris@16: #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_close(NamespaceList) \ Chris@16: BOOST_PP_LIST_FOR_EACH(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_close_op, ~, NamespaceList) \ Chris@16: /**/ Chris@16: Chris@16: #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_close_op(r, data, elem) \ Chris@16: } \ Chris@16: /**/ Chris@16: Chris@16: Chris@16: #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_expand_op(r, data, elem) \ Chris@16: :: elem \ Chris@16: /**/ Chris@16: Chris@16: Chris@16: #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE(Tag, NamespaceList, Name) \ Chris@16: namespace boost { namespace range_detail_microsoft { \ Chris@16: BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_tag(Tag, BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_fullname(NamespaceList, Name)) \ Chris@16: } } \ Chris@16: \ Chris@16: namespace boost { \ Chris@16: BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_mutable_iterator(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_fullname(NamespaceList, Name)) \ Chris@16: BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_const_iterator(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_fullname(NamespaceList, Name)) \ Chris@16: BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_size_type(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_fullname(NamespaceList, Name)) \ Chris@16: } \ Chris@16: \ Chris@16: BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_open(NamespaceList) \ Chris@16: BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_begin(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_fullname(NamespaceList, Name)) \ Chris@16: BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_begin_const(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_fullname(NamespaceList, Name)) \ Chris@16: BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_end(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_fullname(NamespaceList, Name)) \ Chris@16: BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_end_const(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_fullname(NamespaceList, Name)) \ Chris@16: BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_size(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_fullname(NamespaceList, Name)) \ Chris@16: BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_close(NamespaceList) \ Chris@16: /**/ Chris@16: Chris@16: Chris@16: #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_fullname(NamespaceList, Name) \ Chris@16: BOOST_PP_LIST_FOR_EACH(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_expand_op, ~, NamespaceList) :: Name \ Chris@16: /**/ Chris@16: Chris@16: Chris@16: #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_tag(Tag, Fullname) \ Chris@16: template< > \ Chris@16: struct customization_tag< Fullname > : \ Chris@16: customization_tag_of< Tag, Fullname > \ Chris@16: { }; \ Chris@16: /**/ Chris@16: Chris@16: Chris@16: // metafunctions Chris@16: // Chris@16: Chris@16: #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_mutable_iterator(Fullname) \ Chris@16: template< > \ Chris@16: struct BOOST_RANGE_DETAIL_MICROSOFT_range_mutable_iterator< Fullname > : \ Chris@16: range_detail_microsoft::mutable_iterator_of< Fullname > \ Chris@16: { }; \ Chris@16: /**/ Chris@16: Chris@16: Chris@16: #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_const_iterator(Fullname) \ Chris@16: template< > \ Chris@16: struct range_const_iterator< Fullname > : \ Chris@16: range_detail_microsoft::const_iterator_of< Fullname > \ Chris@16: { }; \ Chris@16: /**/ Chris@16: Chris@16: Chris@16: #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_size_type(Fullname) \ Chris@16: template< > \ Chris@16: struct range_size< Fullname > : \ Chris@16: range_detail_microsoft::size_type_of< Fullname > \ Chris@16: { }; \ Chris@16: /**/ Chris@16: Chris@16: Chris@16: // functions Chris@16: // Chris@16: Chris@16: #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_begin(Fullname) \ Chris@16: inline \ Chris@16: boost::range_detail_microsoft::mutable_iterator_of< Fullname >::type \ Chris@16: BOOST_RANGE_DETAIL_MICROSOFT_range_begin(Fullname& x) \ Chris@16: { \ Chris@16: return boost::range_detail_microsoft::begin_of(x); \ Chris@16: } \ Chris@16: /**/ Chris@16: Chris@16: Chris@16: #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_begin_const(Fullname) \ Chris@16: inline \ Chris@16: boost::range_detail_microsoft::const_iterator_of< Fullname >::type \ Chris@16: BOOST_RANGE_DETAIL_MICROSOFT_range_begin(Fullname const& x) \ Chris@16: { \ Chris@16: return boost::range_detail_microsoft::begin_of(x); \ Chris@16: } \ Chris@16: /**/ Chris@16: Chris@16: Chris@16: #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_end(Fullname) \ Chris@16: inline \ Chris@16: boost::range_detail_microsoft::mutable_iterator_of< Fullname >::type \ Chris@16: BOOST_RANGE_DETAIL_MICROSOFT_range_end(Fullname& x) \ Chris@16: { \ Chris@16: return boost::range_detail_microsoft::end_of(x); \ Chris@16: } \ Chris@16: /**/ Chris@16: Chris@16: Chris@16: #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_end_const(Fullname) \ Chris@16: inline \ Chris@16: boost::range_detail_microsoft::const_iterator_of< Fullname >::type \ Chris@16: BOOST_RANGE_DETAIL_MICROSOFT_range_end(Fullname const& x) \ Chris@16: { \ Chris@16: return boost::range_detail_microsoft::end_of(x); \ Chris@16: } \ Chris@16: /**/ Chris@16: Chris@16: Chris@16: #if !defined(BOOST_RANGE_DETAIL_MICROSOFT_RANGE_VERSION_1) Chris@16: Chris@16: #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_size(Fullname) \ Chris@16: /**/ Chris@16: Chris@16: #else Chris@16: Chris@16: #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE_size(Fullname) \ Chris@16: inline \ Chris@16: boost::range_detail_microsoft::size_type_of< Fullname >::type \ Chris@16: boost_range_size(Fullname const& x) \ Chris@16: { \ Chris@16: return boost::range_detail_microsoft::size_of(x); \ Chris@16: } \ Chris@16: /**/ Chris@16: Chris@16: #endif Chris@16: Chris@16: Chris@16: #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE(Tag, NamespaceList, Name, ParamSeqOrCount) \ Chris@16: BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_impl( \ Chris@16: Tag, NamespaceList, Name, \ Chris@16: BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_to_param_seq(ParamSeqOrCount) \ Chris@16: ) \ Chris@16: /**/ Chris@16: Chris@16: #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_to_param_seq(ParamSeqOrCount) \ Chris@16: BOOST_PP_IIF(BOOST_PP_IS_UNARY(ParamSeqOrCount), \ Chris@16: ParamSeqOrCount BOOST_PP_TUPLE_EAT(3), \ Chris@16: BOOST_PP_REPEAT \ Chris@16: )(ParamSeqOrCount, BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_to_param_seq_op, ~) \ Chris@16: /**/ Chris@16: Chris@16: #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_to_param_seq_op(z, n, _) \ Chris@16: (class) \ Chris@16: /**/ Chris@16: Chris@16: Chris@16: #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_impl(Tag, NamespaceList, Name, ParamSeq) \ Chris@16: namespace boost { namespace range_detail_microsoft { \ Chris@16: BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_tag( \ Chris@16: Tag, \ Chris@16: BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params(ParamSeq), \ Chris@16: BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_fullname(NamespaceList, Name, ParamSeq) \ Chris@16: ) \ Chris@16: } } \ Chris@16: \ Chris@16: namespace boost { \ Chris@16: BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_mutable_iterator( \ Chris@16: BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params(ParamSeq), \ Chris@16: BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_fullname(NamespaceList, Name, ParamSeq) \ Chris@16: ) \ Chris@16: BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_const_iterator( \ Chris@16: BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params(ParamSeq), \ Chris@16: BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_fullname(NamespaceList, Name, ParamSeq) \ Chris@16: ) \ Chris@16: \ Chris@16: BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_size_type( \ Chris@16: BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params(ParamSeq), \ Chris@16: BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_fullname(NamespaceList, Name, ParamSeq) \ Chris@16: ) \ Chris@16: } \ Chris@16: \ Chris@16: BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_open(NamespaceList) \ Chris@16: BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_begin( \ Chris@16: BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params(ParamSeq), \ Chris@16: BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_fullname(NamespaceList, Name, ParamSeq) \ Chris@16: ) \ Chris@16: BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_begin_const( \ Chris@16: BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params(ParamSeq), \ Chris@16: BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_fullname(NamespaceList, Name, ParamSeq) \ Chris@16: ) \ Chris@16: BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_end( \ Chris@16: BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params(ParamSeq), \ Chris@16: BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_fullname(NamespaceList, Name, ParamSeq) \ Chris@16: ) \ Chris@16: BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_end_const( \ Chris@16: BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params(ParamSeq), \ Chris@16: BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_fullname(NamespaceList, Name, ParamSeq) \ Chris@16: ) \ Chris@16: BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_size( \ Chris@16: BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params(ParamSeq), \ Chris@16: BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_fullname(NamespaceList, Name, ParamSeq) \ Chris@16: ) \ Chris@16: BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_close(NamespaceList) \ Chris@16: /**/ Chris@16: Chris@16: Chris@16: #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params(ParamSeq) \ Chris@16: BOOST_PP_SEQ_FOR_EACH_I(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params_op, ~, ParamSeq) \ Chris@16: /**/ Chris@16: Chris@16: #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_params_op(r, data, i, elem) \ Chris@16: BOOST_PP_COMMA_IF(i) elem BOOST_PP_CAT(T, i) \ Chris@16: /**/ Chris@16: Chris@16: Chris@16: #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_fullname(NamespaceList, Name, ParamSeq) \ Chris@16: BOOST_PP_LIST_FOR_EACH(BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_namespace_expand_op, ~, NamespaceList) \ Chris@16: :: Name < BOOST_PP_ENUM_PARAMS(BOOST_PP_SEQ_SIZE(ParamSeq), T) > \ Chris@16: /**/ Chris@16: Chris@16: Chris@16: #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_tag(Tag, Params, Fullname) \ Chris@16: template< Params > \ Chris@16: struct customization_tag< Fullname > : \ Chris@16: customization_tag_of< Tag, Fullname > \ Chris@16: { }; \ Chris@16: /**/ Chris@16: Chris@16: Chris@16: // metafunctions Chris@16: // Chris@16: Chris@16: #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_mutable_iterator(Params, Fullname) \ Chris@16: template< Params > \ Chris@16: struct BOOST_RANGE_DETAIL_MICROSOFT_range_mutable_iterator< Fullname > : \ Chris@16: range_detail_microsoft::mutable_iterator_of< Fullname > \ Chris@16: { }; \ Chris@16: /**/ Chris@16: Chris@16: Chris@16: #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_const_iterator(Params, Fullname) \ Chris@16: template< Params > \ Chris@16: struct range_const_iterator< Fullname > : \ Chris@16: range_detail_microsoft::const_iterator_of< Fullname > \ Chris@16: { }; \ Chris@16: /**/ Chris@16: Chris@16: Chris@16: #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_size_type(Params, Fullname) \ Chris@16: template< Params > \ Chris@16: struct range_size< Fullname > : \ Chris@16: range_detail_microsoft::size_type_of< Fullname > \ Chris@16: { }; \ Chris@16: /**/ Chris@16: Chris@16: Chris@16: // functions Chris@16: // Chris@16: Chris@16: #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_begin(Params, Fullname) \ Chris@16: template< Params > inline \ Chris@16: typename boost::range_detail_microsoft::mutable_iterator_of< Fullname >::type \ Chris@16: BOOST_RANGE_DETAIL_MICROSOFT_range_begin(Fullname& x) \ Chris@16: { \ Chris@16: return boost::range_detail_microsoft::begin_of(x); \ Chris@16: } \ Chris@16: /**/ Chris@16: Chris@16: Chris@16: #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_begin_const(Params, Fullname) \ Chris@16: template< Params > inline \ Chris@16: typename boost::range_detail_microsoft::const_iterator_of< Fullname >::type \ Chris@16: BOOST_RANGE_DETAIL_MICROSOFT_range_begin(Fullname const& x) \ Chris@16: { \ Chris@16: return boost::range_detail_microsoft::begin_of(x); \ Chris@16: } \ Chris@16: /**/ Chris@16: Chris@16: Chris@16: #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_end(Params, Fullname) \ Chris@16: template< Params > inline \ Chris@16: typename boost::range_detail_microsoft::mutable_iterator_of< Fullname >::type \ Chris@16: BOOST_RANGE_DETAIL_MICROSOFT_range_end(Fullname& x) \ Chris@16: { \ Chris@16: return boost::range_detail_microsoft::end_of(x); \ Chris@16: } \ Chris@16: /**/ Chris@16: Chris@16: Chris@16: #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_end_const(Params, Fullname) \ Chris@16: template< Params > inline \ Chris@16: typename boost::range_detail_microsoft::const_iterator_of< Fullname >::type \ Chris@16: BOOST_RANGE_DETAIL_MICROSOFT_range_end(Fullname const& x) \ Chris@16: { \ Chris@16: return boost::range_detail_microsoft::end_of(x); \ Chris@16: } \ Chris@16: /**/ Chris@16: Chris@16: Chris@16: #if !defined(BOOST_RANGE_DETAIL_MICROSOFT_RANGE_VERSION_1) Chris@16: Chris@16: #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_size(Params, Fullname) \ Chris@16: /**/ Chris@16: Chris@16: #else Chris@16: Chris@16: #define BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE_size(Params, Fullname) \ Chris@16: template< Params > inline \ Chris@16: typename boost::range_detail_microsoft::size_type_of< Fullname >::type \ Chris@16: boost_range_size(Fullname const& x) \ Chris@16: { \ Chris@16: return boost::range_detail_microsoft::size_of(x); \ Chris@16: } \ Chris@16: /**/ Chris@16: Chris@16: #endif Chris@16: Chris@16: Chris@16: Chris@16: Chris@16: // list_iterator and helpers Chris@16: // Chris@16: Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: Chris@16: // POSITION's header is undocumented, so is NULL. Chris@16: // Chris@16: struct __POSITION; // incomplete, but used as just a pointer. Chris@16: typedef __POSITION *POSITION; Chris@16: Chris@16: Chris@16: namespace boost { namespace range_detail_microsoft { Chris@16: Chris@16: Chris@16: template< Chris@16: class ListT, Chris@16: class Value, Chris@16: class Reference, Chris@16: class Traversal Chris@16: > Chris@16: struct list_iterator; Chris@16: Chris@16: Chris@16: template< Chris@16: class ListT, Chris@16: class Value, Chris@16: class Reference, Chris@16: class Traversal Chris@16: > Chris@16: struct list_iterator_super Chris@16: { Chris@16: typedef typename mpl::if_< is_same, Chris@16: Value&, Chris@16: Reference Chris@16: >::type ref_t; Chris@16: Chris@16: typedef typename mpl::if_< is_same, Chris@16: bidirectional_traversal_tag, Chris@16: Traversal Chris@16: >::type trv_t; Chris@16: Chris@16: typedef iterator_facade< Chris@16: list_iterator, Chris@16: Value, Chris@16: trv_t, Chris@16: ref_t Chris@16: > type; Chris@16: }; Chris@16: Chris@16: Chris@16: template< Chris@16: class ListT, Chris@16: class Value, Chris@16: class Reference = use_default, Chris@16: class Traversal = use_default Chris@16: > Chris@16: struct list_iterator : Chris@16: list_iterator_super::type Chris@16: { Chris@16: private: Chris@16: typedef list_iterator self_t; Chris@16: typedef typename list_iterator_super::type super_t; Chris@16: typedef typename super_t::reference ref_t; Chris@16: Chris@16: public: Chris@16: explicit list_iterator() Chris@16: { } Chris@16: Chris@16: explicit list_iterator(ListT& lst, POSITION pos) : Chris@16: m_plst(boost::addressof(lst)), m_pos(pos) Chris@16: { } Chris@16: Chris@16: template< class, class, class, class > friend struct list_iterator; Chris@16: template< class ListT_, class Value_, class Reference_, class Traversal_> Chris@16: list_iterator(list_iterator const& other) : Chris@16: m_plst(other.m_plst), m_pos(other.m_pos) Chris@16: { } Chris@16: Chris@16: private: Chris@16: ListT *m_plst; Chris@16: POSITION m_pos; Chris@16: Chris@16: friend class iterator_core_access; Chris@16: ref_t dereference() const Chris@16: { Chris@16: BOOST_ASSERT(m_pos != 0 && "out of range"); Chris@16: return m_plst->GetAt(m_pos); Chris@16: } Chris@16: Chris@16: // A B C D x Chris@16: // Head Tail NULL(0) Chris@16: // Chris@16: void increment() Chris@16: { Chris@16: BOOST_ASSERT(m_pos != 0 && "out of range"); Chris@16: m_plst->GetNext(m_pos); Chris@16: } Chris@16: Chris@16: void decrement() Chris@16: { Chris@16: if (m_pos == 0) { Chris@16: m_pos = m_plst->GetTailPosition(); Chris@16: return; Chris@16: } Chris@16: Chris@16: m_plst->GetPrev(m_pos); Chris@16: } Chris@16: Chris@16: bool equal(self_t const& other) const Chris@16: { Chris@16: BOOST_ASSERT(m_plst == other.m_plst && "iterators incompatible"); Chris@16: return m_pos == other.m_pos; Chris@16: } Chris@16: }; Chris@16: Chris@16: Chris@16: // customization helpers Chris@16: // Chris@16: Chris@16: struct array_functions Chris@16: { Chris@16: template< class Iterator, class X > Chris@16: Iterator begin(X& x) Chris@16: { Chris@16: return x.GetData(); Chris@16: } Chris@16: Chris@16: template< class Iterator, class X > Chris@16: Iterator end(X& x) Chris@16: { Chris@16: return begin(x) + x.GetSize(); Chris@16: } Chris@16: }; Chris@16: Chris@16: Chris@16: struct list_functions Chris@16: { Chris@16: template< class Iterator, class X > Chris@16: Iterator begin(X& x) Chris@16: { Chris@16: return Iterator(x, x.GetHeadPosition()); Chris@16: } Chris@16: Chris@16: template< class Iterator, class X > Chris@16: Iterator end(X& x) Chris@16: { Chris@16: return Iterator(x, POSITION(0)); Chris@16: } Chris@16: }; Chris@16: Chris@16: Chris@16: } } // namespace boost::range_detail_microsoft Chris@16: Chris@16: Chris@16: Chris@16: Chris@16: // test Chris@16: // Chris@16: Chris@16: Chris@16: #if defined(BOOST_RANGE_DETAIL_MICROSOFT_TEST) Chris@16: Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: Chris@16: namespace boost { namespace range_detail_microsoft { Chris@16: Chris@16: Chris@16: template< class Range1, class Range2 > Chris@16: bool test_equals(Range1 const& rng1, Range2 const& rng2) Chris@16: { Chris@16: return Chris@16: boost::distance(rng1) == boost::distance(rng2) && Chris@16: std::equal(boost::begin(rng1), boost::end(rng1), boost::begin(rng2)) Chris@16: ; Chris@16: } Chris@16: Chris@16: Chris@16: template< class AssocContainer, class PairT > Chris@16: bool test_find_key_and_mapped(AssocContainer const& ac, PairT const& pa) Chris@16: { Chris@16: typedef typename boost::range_const_iterator::type iter_t; Chris@16: for (iter_t it = boost::const_begin(ac), last = boost::const_end(ac); it != last; ++it) { Chris@16: if (it->first == pa.first && it->second == pa.second) Chris@16: return true; Chris@16: } Chris@16: Chris@16: return false; Chris@16: } Chris@16: Chris@16: Chris@16: // test functions Chris@16: // Chris@16: Chris@16: template< class Range > Chris@16: bool test_emptiness(Range& ) Chris@16: { Chris@16: bool result = true; Chris@16: Chris@16: Range emptyRng; Chris@16: result = result && boost::empty(emptyRng); Chris@16: Chris@16: return result; Chris@16: } Chris@16: Chris@16: Chris@16: template< class Range > Chris@16: bool test_trivial(Range& rng) Chris@16: { Chris@16: bool result = true; Chris@16: Chris@16: // convertibility check Chris@16: typedef typename range_const_iterator::type citer_t; Chris@16: citer_t cit = boost::begin(rng); Chris@16: (void)cit; // unused Chris@16: Chris@16: // mutability check Chris@16: typedef typename range_value::type val_t; Chris@16: val_t v = *boost::begin(rng); Chris@16: *boost::begin(rng) = v; Chris@16: result = result && *boost::begin(rng) == v; Chris@16: Chris@16: return result; Chris@16: } Chris@16: Chris@16: Chris@16: template< class Range > Chris@16: bool test_forward(Range& rng) Chris@16: { Chris@16: boost::function_requires< ForwardRangeConcept >(); Chris@16: Chris@16: bool result = (test_trivial)(rng); Chris@16: Chris@16: typedef typename range_value::type val_t; Chris@16: Chris@16: std::vector saved; Chris@16: std::copy(boost::begin(rng), boost::end(rng), std::back_inserter(saved)); Chris@16: std::rotate(boost::begin(saved), boost::next(boost::begin(saved)), boost::end(saved)); Chris@16: Chris@16: std::rotate(boost::begin(rng), boost::next(boost::begin(rng)), boost::end(rng)); Chris@16: Chris@16: return result && (test_equals)(saved, rng); Chris@16: }; Chris@16: Chris@16: Chris@16: template< class Range > Chris@16: bool test_bidirectional(Range& rng) Chris@16: { Chris@16: boost::function_requires< BidirectionalRangeConcept >(); Chris@16: Chris@16: bool result = (test_forward)(rng); Chris@16: Chris@16: typedef typename range_value::type val_t; Chris@16: Chris@16: std::vector saved; Chris@16: std::copy(boost::begin(rng), boost::end(rng), std::back_inserter(saved)); Chris@16: Chris@16: result = result && (test_equals)( Chris@16: boost::make_iterator_range(boost::rbegin(saved), boost::rend(saved)), Chris@16: boost::make_iterator_range(boost::rbegin(rng), boost::rend(rng)) Chris@16: ); Chris@16: Chris@16: return result; Chris@16: } Chris@16: Chris@16: Chris@16: template< class Range > Chris@16: bool test_random_access(Range& rng) Chris@16: { Chris@16: boost::function_requires< RandomAccessRangeConcept >(); Chris@16: Chris@16: bool result = (test_bidirectional)(rng); Chris@16: Chris@16: typedef typename range_value::type val_t; Chris@16: Chris@16: std::vector saved; Chris@16: std::copy(boost::begin(rng), boost::end(rng), std::back_inserter(saved)); Chris@16: std::sort(boost::begin(saved), boost::end(saved)); Chris@16: Chris@16: std::random_shuffle(boost::begin(rng), boost::end(rng)); Chris@16: std::sort(boost::begin(rng), boost::end(rng)); Chris@16: result = result && (test_equals)(rng, saved); Chris@16: Chris@16: std::random_shuffle(boost::begin(rng), boost::end(rng)); Chris@16: std::stable_sort(boost::begin(rng), boost::end(rng)); Chris@16: result = result && (test_equals)(rng, saved); Chris@16: Chris@16: std::random_shuffle(boost::begin(rng), boost::end(rng)); Chris@16: std::partial_sort(boost::begin(rng), boost::end(rng), boost::end(rng)); Chris@16: result = result && (test_equals)(rng, saved); Chris@16: Chris@16: return result; Chris@16: } Chris@16: Chris@16: Chris@16: // initializer Chris@16: // Chris@16: Chris@16: template< class ArrayT, class SampleRange > Chris@16: bool test_init_array(ArrayT& arr, SampleRange const& sample) Chris@16: { Chris@16: typedef typename range_const_iterator::type iter_t; Chris@16: typedef typename range_value::type val_t; Chris@16: Chris@16: for (iter_t it = boost::const_begin(sample), last = boost::const_end(sample); it != last; ++it) { Chris@16: val_t v = *it; // works around ATL3 CSimpleArray Chris@16: arr.Add(v); Chris@16: } Chris@16: Chris@16: return (test_equals)(arr, sample); Chris@16: } Chris@16: Chris@16: Chris@16: template< class ListT, class SampleRange > Chris@16: bool test_init_list(ListT& lst, SampleRange const& sample) Chris@16: { Chris@16: typedef typename range_const_iterator::type iter_t; Chris@16: Chris@16: for (iter_t it = boost::const_begin(sample), last = boost::const_end(sample); it != last; ++it) { Chris@16: lst.AddTail(*it); Chris@16: } Chris@16: Chris@16: return (test_equals)(lst, sample); Chris@16: } Chris@16: Chris@16: Chris@16: template< class StringT, class SampleRange > Chris@16: bool test_init_string(StringT& str, SampleRange const& sample) Chris@16: { Chris@16: typedef typename range_const_iterator::type iter_t; Chris@16: typedef typename range_value::type val_t; Chris@16: Chris@16: for (iter_t it = boost::const_begin(sample), last = boost::const_end(sample); it != last; ++it) { Chris@16: str += *it; Chris@16: } Chris@16: Chris@16: return (test_equals)(str, sample); Chris@16: } Chris@16: Chris@16: Chris@16: template< class MapT, class SampleMap > Chris@16: bool test_init_map(MapT& map, SampleMap const& sample) Chris@16: { Chris@16: typedef typename range_const_iterator::type iter_t; Chris@16: Chris@16: for (iter_t it = boost::const_begin(sample), last = boost::const_end(sample); it != last; ++it) { Chris@16: map.SetAt(it->first, it->second); Chris@16: } Chris@16: Chris@16: return boost::distance(map) == boost::distance(sample); Chris@16: } Chris@16: Chris@16: Chris@16: // metafunction test Chris@16: // Chris@16: Chris@16: template< class Range, class Iter > Chris@16: struct test_mutable_iter : Chris@16: boost::is_same< typename boost::BOOST_RANGE_DETAIL_MICROSOFT_range_mutable_iterator::type, Iter > Chris@16: { }; Chris@16: Chris@16: Chris@16: template< class Range, class Iter > Chris@16: struct test_const_iter : Chris@16: boost::is_same< typename boost::range_const_iterator::type, Iter > Chris@16: { }; Chris@16: Chris@16: Chris@16: } } // namespace boost::range_detail_microsoft Chris@16: Chris@16: Chris@16: #endif // defined(BOOST_RANGE_DETAIL_MICROSOFT_TEST) Chris@16: Chris@16: Chris@16: Chris@16: #endif