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