From 6d46ce412f21cd8cbaa9e44c9567855a6029332c Mon Sep 17 00:00:00 2001 From: Neil Groves Date: Mon, 10 Jan 2011 06:35:02 +0000 Subject: [PATCH] [range] - merge the tested changes from the trunk in preparation for the 1.46 release. [SVN r67905] --- doc/boost_range.qbk | 2 + doc/html/index.html | 5 +- doc/html/quickbook_HTML.manifest | 2 + .../range/concepts/bidirectional_range.html | 16 +- doc/html/range/concepts/concept_checking.html | 2 +- doc/html/range/concepts/forward_range.html | 10 +- .../range/concepts/random_access_range.html | 12 +- .../range/concepts/single_pass_range.html | 16 +- doc/html/range/history_ack.html | 4 +- doc/html/range/introduction.html | 6 +- doc/html/range/mfc_atl.html | 4 +- doc/html/range/reference.html | 1 + .../reference/adaptors/introduction.html | 6 +- .../range/reference/adaptors/reference.html | 1 + .../reference/adaptors/reference/strided.html | 10 +- .../adaptors/reference/tokenized.html | 6 +- .../adaptors/reference/type_erased.html | 305 +++++++++ .../reference/algorithms/heap/make_heap.html | 10 +- .../reference/algorithms/heap/pop_heap.html | 12 +- .../reference/algorithms/heap/push_heap.html | 12 +- .../reference/algorithms/heap/sort_heap.html | 12 +- .../reference/algorithms/mutating/copy.html | 12 +- .../algorithms/mutating/copy_backward.html | 12 +- .../reference/algorithms/mutating/fill.html | 10 +- .../reference/algorithms/mutating/fill_n.html | 10 +- .../algorithms/mutating/generate.html | 12 +- .../algorithms/mutating/inplace_merge.html | 16 +- .../reference/algorithms/mutating/merge.html | 16 +- .../algorithms/mutating/nth_element.html | 10 +- .../algorithms/mutating/partial_sort.html | 10 +- .../algorithms/mutating/partition.html | 10 +- .../algorithms/mutating/random_shuffle.html | 12 +- .../reference/algorithms/mutating/remove.html | 10 +- .../algorithms/mutating/remove_copy.html | 10 +- .../algorithms/mutating/remove_copy_if.html | 10 +- .../algorithms/mutating/remove_if.html | 10 +- .../algorithms/mutating/replace.html | 10 +- .../algorithms/mutating/replace_copy.html | 10 +- .../algorithms/mutating/replace_copy_if.html | 10 +- .../algorithms/mutating/replace_if.html | 10 +- .../algorithms/mutating/reverse.html | 10 +- .../algorithms/mutating/reverse_copy.html | 10 +- .../reference/algorithms/mutating/rotate.html | 12 +- .../algorithms/mutating/rotate_copy.html | 12 +- .../reference/algorithms/mutating/sort.html | 10 +- .../algorithms/mutating/stable_partition.html | 10 +- .../algorithms/mutating/stable_sort.html | 10 +- .../algorithms/mutating/swap_ranges.html | 10 +- .../algorithms/mutating/transform.html | 12 +- .../reference/algorithms/mutating/unique.html | 10 +- .../algorithms/mutating/unique_copy.html | 10 +- .../reference/algorithms/new/copy_n.html | 10 +- .../range/reference/algorithms/new/erase.html | 10 +- .../reference/algorithms/new/for_each.html | 10 +- .../reference/algorithms/new/insert.html | 10 +- .../range/reference/algorithms/new/iota.html | 10 +- .../reference/algorithms/new/is_sorted.html | 10 +- .../reference/algorithms/new/overwrite.html | 10 +- .../reference/algorithms/new/push_back.html | 10 +- .../reference/algorithms/new/push_front.html | 10 +- .../algorithms/new/remove_erase.html | 10 +- .../algorithms/new/remove_erase_if.html | 10 +- .../non_mutating/adjacent_find.html | 10 +- .../non_mutating/binary_search.html | 12 +- .../algorithms/non_mutating/count.html | 10 +- .../algorithms/non_mutating/count_if.html | 10 +- .../algorithms/non_mutating/equal.html | 10 +- .../algorithms/non_mutating/equal_range.html | 12 +- .../algorithms/non_mutating/find.html | 10 +- .../algorithms/non_mutating/find_end.html | 10 +- .../non_mutating/find_first_of.html | 10 +- .../algorithms/non_mutating/find_if.html | 12 +- .../algorithms/non_mutating/for_each.html | 10 +- .../non_mutating/lexicographical_compare.html | 10 +- .../algorithms/non_mutating/lower_bound.html | 12 +- .../algorithms/non_mutating/max_element.html | 10 +- .../algorithms/non_mutating/min_element.html | 10 +- .../algorithms/non_mutating/mismatch.html | 12 +- .../algorithms/non_mutating/search.html | 10 +- .../algorithms/non_mutating/search_n.html | 10 +- .../algorithms/non_mutating/upper_bound.html | 12 +- .../algorithms/numeric/accumulate.html | 14 +- .../numeric/adjacent_difference.html | 16 +- .../algorithms/numeric/inner_product.html | 16 +- .../algorithms/numeric/partial_sum.html | 16 +- .../permutation/next_permutation.html | 10 +- .../permutation/prev_permutation.html | 10 +- .../reference/algorithms/set/includes.html | 12 +- .../algorithms/set/set_difference.html | 12 +- .../algorithms/set/set_intersection.html | 12 +- .../set/set_symmetric_difference.html | 12 +- .../reference/algorithms/set/set_union.html | 12 +- .../concept_implementation/semantics.html | 2 +- .../semantics/functions.html | 25 +- doc/html/range/reference/ranges.html | 7 +- .../range/reference/ranges/any_range.html | 177 ++++++ .../reference/ranges/counting_range.html | 14 +- doc/html/range/reference/ranges/irange.html | 10 +- .../range/reference/ranges/istream_range.html | 6 +- .../reference/utilities/iterator_range.html | 6 +- doc/html/range/reference/utilities/join.html | 4 +- .../range/reference/utilities/sub_range.html | 2 +- doc/reference/adaptors.qbk | 1 + doc/reference/adaptors/strided.qbk | 2 +- doc/reference/adaptors/type_erased.qbk | 151 +++++ doc/reference/ranges.qbk | 1 + doc/reference/ranges/any_range.qbk | 115 ++++ doc/reference/semantics.qbk | 4 +- include/boost/range/adaptor/sliced.hpp | 1 + include/boost/range/adaptor/strided.hpp | 303 ++++++--- include/boost/range/adaptor/type_erased.hpp | 218 +++++-- include/boost/range/any_range.hpp | 204 ++++++ include/boost/range/begin.hpp | 23 +- include/boost/range/concepts.hpp | 23 +- include/boost/range/detail/any_iterator.hpp | 587 +++++++++++++++++ .../range/detail/any_iterator_buffer.hpp | 117 ++++ .../range/detail/any_iterator_interface.hpp | 258 ++++++++ .../range/detail/any_iterator_wrapper.hpp | 590 ++++++++++++++++++ include/boost/range/detail/begin.hpp | 28 +- include/boost/range/detail/end.hpp | 37 +- include/boost/range/detail/safe_bool.hpp | 72 +++ include/boost/range/end.hpp | 23 +- include/boost/range/iterator_range_core.hpp | 20 +- include/boost/range/size.hpp | 35 +- test/Jamfile.v2 | 4 + test/adaptor_test/strided.cpp | 16 +- test/adaptor_test/type_erased.cpp | 481 ++++++++++++++ test/adaptor_test/type_erased_example.cpp | 115 ++++ test/algorithm_test/count_if.cpp | 7 +- test/algorithm_test/find.cpp | 127 ++-- test/algorithm_test/find_end.cpp | 281 +++++---- test/algorithm_test/find_first_of.cpp | 271 ++++---- test/algorithm_test/find_if.cpp | 161 +++-- test/algorithm_test/lower_bound.cpp | 274 ++++---- test/algorithm_test/max_element.cpp | 213 ++++--- test/algorithm_test/min_element.cpp | 211 +++---- test/algorithm_test/partition.cpp | 165 +++-- test/algorithm_test/stable_partition.cpp | 172 +++-- test/algorithm_test/unique.cpp | 255 ++++---- test/algorithm_test/upper_bound.cpp | 259 ++++---- test/begin.cpp | 119 ++++ test/end.cpp | 119 ++++ test/extension_size.cpp | 52 +- 143 files changed, 5587 insertions(+), 2015 deletions(-) create mode 100644 doc/html/range/reference/adaptors/reference/type_erased.html create mode 100644 doc/html/range/reference/ranges/any_range.html create mode 100644 doc/reference/adaptors/type_erased.qbk create mode 100644 doc/reference/ranges/any_range.qbk create mode 100644 include/boost/range/any_range.hpp create mode 100644 include/boost/range/detail/any_iterator.hpp create mode 100644 include/boost/range/detail/any_iterator_buffer.hpp create mode 100644 include/boost/range/detail/any_iterator_interface.hpp create mode 100644 include/boost/range/detail/any_iterator_wrapper.hpp mode change 100755 => 100644 include/boost/range/detail/begin.hpp mode change 100755 => 100644 include/boost/range/detail/end.hpp create mode 100644 include/boost/range/detail/safe_bool.hpp create mode 100644 test/adaptor_test/type_erased.cpp create mode 100644 test/adaptor_test/type_erased_example.cpp create mode 100644 test/begin.cpp create mode 100644 test/end.cpp diff --git a/doc/boost_range.qbk b/doc/boost_range.qbk index 80bbf06..be09bc6 100644 --- a/doc/boost_range.qbk +++ b/doc/boost_range.qbk @@ -78,6 +78,7 @@ [def __range_adaptors_reversed__ [link range.reference.adaptors.reference.reversed reversed]] [def __range_adaptors_sliced__ [link range.reference.adaptors.reference.sliced sliced]] [def __range_adaptors_strided__ [link range.reference.adaptors.reference.strided strided]] +[def __range_adaptors_type_erased__ [link range.reference.adaptors.reference.type_erased type_erased]] [def __range_adaptors_tokenized__ [link range.reference.adaptors.reference.tokenized tokenized]] [def __range_adaptors_transformed__ [link range.reference.adaptors.reference.transformed transformed]] [def __range_adaptors_uniqued__ [link range.reference.adaptors.reference.uniqued uniqued]] @@ -174,6 +175,7 @@ [def __sgi_inner_product__ [@http://www.sgi.com/tech/stl/inner_product.html inner_product]] [def __sgi_partial_sum__ [@http://www.sgi.com/tech/stl/partial_sum.html partial_sum]] +[def __type_erasure_article__ [@http://www.artima.com/cppsource/type_erasure.html type erasure article]] Boost.Range is a collection of concepts and utilities, range-based algorithms, as well as range adaptors that allow for efficient and expressive code. diff --git a/doc/html/index.html b/doc/html/index.html index 8b74c06..1be23d5 100644 --- a/doc/html/index.html +++ b/doc/html/index.html @@ -30,7 +30,7 @@
-

+

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)

@@ -82,6 +82,7 @@
Provided Ranges
+
any_range
counting_range
istream_range
irange
@@ -143,7 +144,7 @@

- +

Last revised: December 23, 2010 at 17:58:25 GMT

Last revised: January 01, 2011 at 16:31:27 GMT


diff --git a/doc/html/quickbook_HTML.manifest b/doc/html/quickbook_HTML.manifest index b12e40e..1b32f72 100644 --- a/doc/html/quickbook_HTML.manifest +++ b/doc/html/quickbook_HTML.manifest @@ -30,6 +30,7 @@ range/reference/adaptors/reference/replaced_if.html range/reference/adaptors/reference/reversed.html range/reference/adaptors/reference/sliced.html range/reference/adaptors/reference/strided.html +range/reference/adaptors/reference/type_erased.html range/reference/adaptors/reference/tokenized.html range/reference/adaptors/reference/transformed.html range/reference/adaptors/reference/uniqued.html @@ -118,6 +119,7 @@ range/reference/algorithms/numeric/adjacent_difference.html range/reference/algorithms/numeric/inner_product.html range/reference/algorithms/numeric/partial_sum.html range/reference/ranges.html +range/reference/ranges/any_range.html range/reference/ranges/counting_range.html range/reference/ranges/istream_range.html range/reference/ranges/irange.html diff --git a/doc/html/range/concepts/bidirectional_range.html b/doc/html/range/concepts/bidirectional_range.html index ba06db0..6e3dc8c 100644 --- a/doc/html/range/concepts/bidirectional_range.html +++ b/doc/html/range/concepts/bidirectional_range.html @@ -27,7 +27,7 @@ Bidirectional Range
- + Notation
@@ -65,7 +65,7 @@
- + Description

@@ -75,7 +75,7 @@ Traversal Iterator.

- + Refinement of
@@ -83,7 +83,7 @@ Forward Range

- + Associated types
@@ -136,7 +136,7 @@
- + Valid expressions
@@ -221,7 +221,7 @@
- + Complexity guarantees
@@ -232,7 +232,7 @@ Forward Range.

- + Invariants
@@ -272,7 +272,7 @@
- + See also

diff --git a/doc/html/range/concepts/concept_checking.html b/doc/html/range/concepts/concept_checking.html index db21dbb..20a2fbb 100644 --- a/doc/html/range/concepts/concept_checking.html +++ b/doc/html/range/concepts/concept_checking.html @@ -79,7 +79,7 @@

- + See also

diff --git a/doc/html/range/concepts/forward_range.html b/doc/html/range/concepts/forward_range.html index 95b7dac..7937f8c 100644 --- a/doc/html/range/concepts/forward_range.html +++ b/doc/html/range/concepts/forward_range.html @@ -27,7 +27,7 @@ Forward Range

- + Notation
@@ -65,7 +65,7 @@
- + Description

@@ -73,14 +73,14 @@ Traversal Iterator.

- + Refinement of

Single Pass Range

- + Associated types
@@ -132,7 +132,7 @@
- + See also

diff --git a/doc/html/range/concepts/random_access_range.html b/doc/html/range/concepts/random_access_range.html index fa49539..3124ddc 100644 --- a/doc/html/range/concepts/random_access_range.html +++ b/doc/html/range/concepts/random_access_range.html @@ -27,7 +27,7 @@ Random Access Range

- + Description

@@ -35,7 +35,7 @@ Access Traversal Iterator.

- + Refinement of
@@ -43,7 +43,7 @@ Bidirectional Range

- + Valid expressions
@@ -89,7 +89,7 @@
- + Expression semantics
@@ -139,7 +139,7 @@
- + Complexity guarantees
@@ -147,7 +147,7 @@ boost::size(a) completes in amortized constant time.

- + Invariants
diff --git a/doc/html/range/concepts/single_pass_range.html b/doc/html/range/concepts/single_pass_range.html index a9acb72..273692a 100644 --- a/doc/html/range/concepts/single_pass_range.html +++ b/doc/html/range/concepts/single_pass_range.html @@ -27,7 +27,7 @@ Single Pass Range
- + Notation
@@ -65,7 +65,7 @@
- + Description

@@ -73,7 +73,7 @@ Pass Iterator.

- + Associated types
@@ -126,7 +126,7 @@
- + Valid expressions
@@ -198,7 +198,7 @@
- + Expression semantics
@@ -266,7 +266,7 @@
- + Complexity guarantees
@@ -276,7 +276,7 @@ constant time.

- + Invariants
@@ -316,7 +316,7 @@
- + See also

diff --git a/doc/html/range/history_ack.html b/doc/html/range/history_ack.html index 8c99a63..49355b5 100644 --- a/doc/html/range/history_ack.html +++ b/doc/html/range/history_ack.html @@ -26,7 +26,7 @@ History and Acknowledgement

- + Version 1 - before Boost 1.43

@@ -79,7 +79,7 @@ The concept checks and their documentation was provided by Daniel Walker.

- + Version 2 - Boost 1.43 and beyond

diff --git a/doc/html/range/introduction.html b/doc/html/range/introduction.html index 07af796..a68d315 100644 --- a/doc/html/range/introduction.html +++ b/doc/html/range/introduction.html @@ -70,7 +70,7 @@

- + Example - Iterate over the values in a map

@@ -84,7 +84,7 @@

- + Example - Iterate over the keys in a map

@@ -98,7 +98,7 @@

- + Example - Push the even values from a map in reverse order into the container target

diff --git a/doc/html/range/mfc_atl.html b/doc/html/range/mfc_atl.html index 91938cc..2ca51fd 100644 --- a/doc/html/range/mfc_atl.html +++ b/doc/html/range/mfc_atl.html @@ -34,7 +34,7 @@
References
- + Introduction

@@ -100,7 +100,7 @@

- + Overview

diff --git a/doc/html/range/reference.html b/doc/html/range/reference.html index f8246fb..50f6ed0 100644 --- a/doc/html/range/reference.html +++ b/doc/html/range/reference.html @@ -58,6 +58,7 @@

Provided Ranges
+
any_range
counting_range
istream_range
irange
diff --git a/doc/html/range/reference/adaptors/introduction.html b/doc/html/range/reference/adaptors/introduction.html index d3e606b..4991499 100644 --- a/doc/html/range/reference/adaptors/introduction.html +++ b/doc/html/range/reference/adaptors/introduction.html @@ -122,7 +122,7 @@ situations, you will really appreciate the succinctness of operator|().

- + Composition of Adaptors
@@ -169,7 +169,7 @@ is the design solution to this problem.

- + Range Adaptor alternative to copy_if algorithm
@@ -186,7 +186,7 @@

- + Range Adaptor alternative to count_if algorithm
diff --git a/doc/html/range/reference/adaptors/reference.html b/doc/html/range/reference/adaptors/reference.html index dffb6fe..4e5b99a 100644 --- a/doc/html/range/reference/adaptors/reference.html +++ b/doc/html/range/reference/adaptors/reference.html @@ -39,6 +39,7 @@
reversed
sliced
strided
+
type_erased
tokenized
transformed
uniqued
diff --git a/doc/html/range/reference/adaptors/reference/strided.html b/doc/html/range/reference/adaptors/reference/strided.html index e79f8cf..592b83e 100644 --- a/doc/html/range/reference/adaptors/reference/strided.html +++ b/doc/html/range/reference/adaptors/reference/strided.html @@ -7,7 +7,7 @@ - + @@ -20,7 +20,7 @@

-PrevUpHomeNext +PrevUpHomeNext
@@ -77,9 +77,7 @@
  • Precondition: 0 - <= n - and boost::size(rng) - is a valid expression. + <= n.
  • Returns: A new range based on rng where traversal is performed @@ -145,7 +143,7 @@
    -PrevUpHomeNext +PrevUpHomeNext
    diff --git a/doc/html/range/reference/adaptors/reference/tokenized.html b/doc/html/range/reference/adaptors/reference/tokenized.html index 242fbc2..2dfa506 100644 --- a/doc/html/range/reference/adaptors/reference/tokenized.html +++ b/doc/html/range/reference/adaptors/reference/tokenized.html @@ -6,7 +6,7 @@ - + @@ -20,7 +20,7 @@
    -PrevUpHomeNext +PrevUpHomeNext
    @@ -149,7 +149,7 @@
    -PrevUpHomeNext +PrevUpHomeNext
    diff --git a/doc/html/range/reference/adaptors/reference/type_erased.html b/doc/html/range/reference/adaptors/reference/type_erased.html new file mode 100644 index 0000000..87649ee --- /dev/null +++ b/doc/html/range/reference/adaptors/reference/type_erased.html @@ -0,0 +1,305 @@ + + + +type_erased + + + + + + + + + + + + + + + +
    Boost C++ LibrariesHomeLibrariesPeopleFAQMore
    +
    +
    +PrevUpHomeNext +
    +
    + + +
    ++++ + + + + + + + + + + + + + + +
    +

    + Syntax +

    +
    +

    + Code +

    +
    +

    + Pipe +

    +
    +

    + rng | + boost::adaptors::type_erased<Value, + Traversal, + Reference, + Difference, + Buffer>() +

    +
    +

    + Function +

    +
    +

    + boost::adaptors::type_erase(rng, + boost::adaptors::type_erased<Value, + Traversal, + Reference, + Difference, + Buffer>) +

    +
    +

    + Please note that it is frequently unnecessary to use the type_erased adaptor. It is often better + to use the implicit conversion to any_range. +

    +

    + Let Rng be the type of + rng. +

    +
      +
    • +

      + Template parameters: +

      +
        +
      • + Value is the + value_type for + the any_range. + If this is set to boost::use_default, Value + will be calculated from the range type when the adaptor is applied. +
      • +
      • + Traversal is + the tag used to identify the traversal of the resultant range. + Frequently it is desireable to set a traversal category lower + than the source container or range to maximize the number of + ranges that can convert to the any_range. + If this is left as boost::use_default then Traversal + will be typename boost::iterator_traversal<boost::range_iterator<Rng>::type>::type +
      • +
      • + Reference is + the reference + for the any_range. + boost::use_default will equate to + typename range_reference<Rng>::type. +
      • +
      • + Difference is + the difference_type + for the any_range. boost::use_default + will equate to typename + boost::range_difference<Rng>::type +
      • +
      • + Buffer is the + storage used to allocate the underlying iterator wrappers. This + can typically be ignored, but is available as a template parameter + for customization. Buffer must be a model of the AnyIteratorBufferConcept. +
      • +
      +
    • +
    • + Precondition: Traversal + is one of { boost::use_default, boost::single_pass_traversal_tag, boost::forward_traversal_tag, boost::bidirectional_traversal_tag, boost::random_access_traversal_tag + } +
    • +
    • + Returns: The returned value is the + same as typename any_range_type_generator< Rng, Value, Traversal, Reference, Difference, Buffer + > that represents rng in a type-erased manner. +
    • +
    • + Range Category: Single + Pass Range +
    • +
    • + Returned Range Category: if Traversal was specified as boost::use_default then typename boost::iterator_traversal<boost::range_iterator<Rng>::type>::type, + otherwise Traversal. +
    • +
    +
    + + AnyIteratorBufferConcept +
    +

    + +

    +
    class AnyIteratorBufferConcept
    +{
    +public:
    +    AnyIteratorBufferConcept();
    +    ~AnyIteratorBufferConcept();
    +
    +    // bytes is the requested size to allocate. This function
    +    // must return a pointer to an adequate area of memory.
    +    // throws: bad_alloc
    +    //
    +    // The buffer will only ever have zero or one
    +    // outstanding memory allocations.
    +    void* allocate(std::size_t bytes);
    +
    +    // deallocate this buffer
    +    void deallocate();
    +};
    +
    +

    +

    +
    + +

    + +

    +
    #include <boost/range/adaptor/type_erased.hpp>
    +#include <boost/range/algorithm/copy.hpp>
    +#include <boost/assign.hpp>
    +#include <boost/foreach.hpp>
    +#include <algorithm>
    +#include <iostream>
    +#include <list>
    +#include <vector>
    +
    +// The client interface from an OO perspective merely requires a sequence
    +// of integers that can be forward traversed
    +typedef boost::any_range<
    +    int
    +  , boost::forward_traversal_tag
    +  , int
    +  , std::ptrdiff_t
    +> integer_range;
    +
    +namespace server
    +{
    +    void display_integers(const integer_range& rng)
    +    {
    +        boost::copy(rng,
    +                    std::ostream_iterator<int>(std::cout, ","));
    +
    +        std::cout << std::endl;
    +    }
    +}
    +
    +namespace client
    +{
    +    void run()
    +    {
    +        using namespace boost::assign;
    +        using namespace boost::adaptors;
    +
    +        // Under most conditions one would simply use an appropriate
    +        // any_range as a function parameter. The type_erased adaptor
    +        // is often superfluous. However because the type_erased
    +        // adaptor is applied to a range, we can use default template
    +        // arguments that are generated in conjunction with the
    +        // range type to which we are applying the adaptor.
    +
    +        std::vector<int> input;
    +        input += 1,2,3,4,5;
    +
    +        // Note that this call is to a non-template function
    +        server::display_integers(input);
    +
    +        std::list<int> input2;
    +        input2 += 6,7,8,9,10;
    +
    +        // Note that this call is to the same non-tempate function
    +        server::display_integers(input2);
    +
    +        input2.clear();
    +        input2 += 11,12,13,14,15;
    +
    +        // Calling using the adaptor looks like this:
    +        // Notice that here I have a type_erased that would be a
    +        // bidirectional_traversal_tag, but this is convertible
    +        // to the forward_traversal_tag equivalent hence this
    +        // works.
    +        server::display_integers(input2 | type_erased<>());
    +
    +        // However we may simply wish to define an adaptor that
    +        // takes a range and makes it into an appropriate
    +        // forward_traversal any_range...
    +        typedef boost::adaptors::type_erased<
    +            boost::use_default
    +          , boost::forward_traversal_tag
    +        > type_erased_forward;
    +
    +        // This adaptor can turn other containers with different
    +        // value_types and reference_types into the appropriate
    +        // any_range.
    +
    +        server::display_integers(input2 | type_erased_forward());
    +    }
    +}
    +
    +int main(int argc, const char* argv[])
    +{
    +    client::run();
    +    return 0;
    +}
    +
    +

    +

    +
    +

    + This would produce the output: +

    +
    1,2,3,4,5
    +6,7,8,9,10
    +11,12,13,14,15
    +11,12,13,14,15
    +
    +

    +

    +
    + + + +
    +
    +
    +PrevUpHomeNext +
    + + diff --git a/doc/html/range/reference/algorithms/heap/make_heap.html b/doc/html/range/reference/algorithms/heap/make_heap.html index a7a201c..3d4b6ec 100644 --- a/doc/html/range/reference/algorithms/heap/make_heap.html +++ b/doc/html/range/reference/algorithms/heap/make_heap.html @@ -27,7 +27,7 @@ make_heap
    - + Prototype

    @@ -48,7 +48,7 @@

    - + Description

    @@ -60,14 +60,14 @@ the predicate versions.

    - + Definition

    Defined in the header file boost/range/algorithm/heap_algorithm.hpp

    - + Requirements

    @@ -118,7 +118,7 @@

- + Complexity

diff --git a/doc/html/range/reference/algorithms/heap/pop_heap.html b/doc/html/range/reference/algorithms/heap/pop_heap.html index 4926fa5..d8f0283 100644 --- a/doc/html/range/reference/algorithms/heap/pop_heap.html +++ b/doc/html/range/reference/algorithms/heap/pop_heap.html @@ -27,7 +27,7 @@ pop_heap

- + Prototype

@@ -48,7 +48,7 @@

- + Description

@@ -62,14 +62,14 @@ the predicate versions.

- + Definition

Defined in the header file boost/range/algorithm/heap_algorithm.hpp

- + Requirements

@@ -120,7 +120,7 @@

- + Precondition:
    @@ -132,7 +132,7 @@
- + Complexity

diff --git a/doc/html/range/reference/algorithms/heap/push_heap.html b/doc/html/range/reference/algorithms/heap/push_heap.html index 976aece..4223024 100644 --- a/doc/html/range/reference/algorithms/heap/push_heap.html +++ b/doc/html/range/reference/algorithms/heap/push_heap.html @@ -27,7 +27,7 @@ push_heap

- + Prototype

@@ -48,7 +48,7 @@

- + Description

@@ -62,14 +62,14 @@ the predicate versions.

- + Definition

Defined in the header file boost/range/algorithm/heap_algorithm.hpp

- + Requirements

@@ -120,7 +120,7 @@

- + Precondition:
    @@ -132,7 +132,7 @@
- + Complexity

diff --git a/doc/html/range/reference/algorithms/heap/sort_heap.html b/doc/html/range/reference/algorithms/heap/sort_heap.html index 4366d76..7667438 100644 --- a/doc/html/range/reference/algorithms/heap/sort_heap.html +++ b/doc/html/range/reference/algorithms/heap/sort_heap.html @@ -27,7 +27,7 @@ sort_heap

- + Prototype

@@ -48,7 +48,7 @@

- + Description

@@ -61,14 +61,14 @@ the predicate versions.

- + Definition

Defined in the header file boost/range/algorithm/heap_algorithm.hpp

- + Requirements

@@ -119,14 +119,14 @@

- + Precondition:

rng is a heap.

- + Complexity

diff --git a/doc/html/range/reference/algorithms/mutating/copy.html b/doc/html/range/reference/algorithms/mutating/copy.html index bfa49dc..fd096ff 100644 --- a/doc/html/range/reference/algorithms/mutating/copy.html +++ b/doc/html/range/reference/algorithms/mutating/copy.html @@ -27,7 +27,7 @@ copy

- + Prototype

@@ -39,7 +39,7 @@

- + Description

@@ -50,14 +50,14 @@ distance(source_rng)

- + Definition

Defined in the header file boost/range/algorithm/copy.hpp

- + Requirements
    @@ -78,7 +78,7 @@
- + Precondition:
    @@ -92,7 +92,7 @@
- + Complexity

diff --git a/doc/html/range/reference/algorithms/mutating/copy_backward.html b/doc/html/range/reference/algorithms/mutating/copy_backward.html index 2c79bf9..29139c1 100644 --- a/doc/html/range/reference/algorithms/mutating/copy_backward.html +++ b/doc/html/range/reference/algorithms/mutating/copy_backward.html @@ -27,7 +27,7 @@ copy_backward

- + Prototype

@@ -41,7 +41,7 @@

- + Description

@@ -59,14 +59,14 @@ denotes the end of the output sequence.

- + Definition

Defined in the header file boost/range/algorithm/copy_backward.hpp

- + Requirements
    @@ -87,7 +87,7 @@
- + Precondition:
    @@ -101,7 +101,7 @@
- + Complexity

diff --git a/doc/html/range/reference/algorithms/mutating/fill.html b/doc/html/range/reference/algorithms/mutating/fill.html index 77c78c6..ea3fec4 100644 --- a/doc/html/range/reference/algorithms/mutating/fill.html +++ b/doc/html/range/reference/algorithms/mutating/fill.html @@ -27,7 +27,7 @@ fill

- + Prototype

@@ -39,7 +39,7 @@

- + Description

@@ -48,14 +48,14 @@ in the range rng.

- + Definition

Defined in the header file boost/range/algorithm/fill.hpp

- + Requirements
    @@ -78,7 +78,7 @@
- + Complexity

diff --git a/doc/html/range/reference/algorithms/mutating/fill_n.html b/doc/html/range/reference/algorithms/mutating/fill_n.html index 5a7fb40..56594c9 100644 --- a/doc/html/range/reference/algorithms/mutating/fill_n.html +++ b/doc/html/range/reference/algorithms/mutating/fill_n.html @@ -27,7 +27,7 @@ fill_n

- + Prototype

@@ -39,7 +39,7 @@

- + Description

@@ -47,14 +47,14 @@ val to n elements in the range rng begining with boost::begin(rng).

- + Definition

Defined in the header file boost/range/algorithm/fill_n.hpp

- + Requirements
    @@ -77,7 +77,7 @@
- + Complexity

diff --git a/doc/html/range/reference/algorithms/mutating/generate.html b/doc/html/range/reference/algorithms/mutating/generate.html index d28c8ca..c4f568d 100644 --- a/doc/html/range/reference/algorithms/mutating/generate.html +++ b/doc/html/range/reference/algorithms/mutating/generate.html @@ -27,7 +27,7 @@ generate

- + Prototype

@@ -42,7 +42,7 @@

- + Description

@@ -52,14 +52,14 @@ Returns the resultant range.

- + Definition

Defined in the header file boost/range/algorithm/generate.hpp

- + Requirements
    @@ -83,7 +83,7 @@
- + Precondition:
    @@ -97,7 +97,7 @@
- + Complexity

diff --git a/doc/html/range/reference/algorithms/mutating/inplace_merge.html b/doc/html/range/reference/algorithms/mutating/inplace_merge.html index a14c627..ced6655 100644 --- a/doc/html/range/reference/algorithms/mutating/inplace_merge.html +++ b/doc/html/range/reference/algorithms/mutating/inplace_merge.html @@ -27,7 +27,7 @@ inplace_merge

- + Prototype

@@ -58,7 +58,7 @@

- + Description

@@ -71,14 +71,14 @@ input range is preserved.

- + Definition

Defined in the header file boost/range/algorithm/inplace_merge.hpp

- + Requirements

@@ -115,11 +115,11 @@ argument types.

- + Precondition:
- + For the non-predicate version:
@@ -142,7 +142,7 @@
- + For the predicate version:
@@ -163,7 +163,7 @@
- + Complexity

diff --git a/doc/html/range/reference/algorithms/mutating/merge.html b/doc/html/range/reference/algorithms/mutating/merge.html index f847d5d..9d0ce89 100644 --- a/doc/html/range/reference/algorithms/mutating/merge.html +++ b/doc/html/range/reference/algorithms/mutating/merge.html @@ -27,7 +27,7 @@ merge

- + Prototype

@@ -56,7 +56,7 @@

- + Description

@@ -75,14 +75,14 @@ version uses the predicate instead of operator<().

- + Definition

Defined in the header file boost/range/algorithm/merge.hpp

- + Requirements

@@ -150,11 +150,11 @@

- + Precondition:
- + For the non-predicate version:
@@ -194,7 +194,7 @@
- + For the predicate version:
@@ -230,7 +230,7 @@
- + Complexity

diff --git a/doc/html/range/reference/algorithms/mutating/nth_element.html b/doc/html/range/reference/algorithms/mutating/nth_element.html index 624dfb2..16846cd 100644 --- a/doc/html/range/reference/algorithms/mutating/nth_element.html +++ b/doc/html/range/reference/algorithms/mutating/nth_element.html @@ -27,7 +27,7 @@ nth_element

- + Prototype

@@ -58,7 +58,7 @@

- + Description

@@ -69,14 +69,14 @@ is the same as the element that would be in that position if rng has been sorted.

- + Definition

Defined in the header file boost/range/algorithm/nth_element.hpp

- + Requirements

@@ -127,7 +127,7 @@

- + Complexity

diff --git a/doc/html/range/reference/algorithms/mutating/partial_sort.html b/doc/html/range/reference/algorithms/mutating/partial_sort.html index 12a4024..33fb1df 100644 --- a/doc/html/range/reference/algorithms/mutating/partial_sort.html +++ b/doc/html/range/reference/algorithms/mutating/partial_sort.html @@ -27,7 +27,7 @@ partial_sort

- + Prototype

@@ -58,7 +58,7 @@

- + Description

@@ -74,14 +74,14 @@ predicate instead.

- + Definition

Defined in the header file boost/range/algorithm/partial_sort.hpp

- + Requirements

@@ -132,7 +132,7 @@

- + Complexity

diff --git a/doc/html/range/reference/algorithms/mutating/partition.html b/doc/html/range/reference/algorithms/mutating/partition.html index 0cd0c73..d659dd4 100644 --- a/doc/html/range/reference/algorithms/mutating/partition.html +++ b/doc/html/range/reference/algorithms/mutating/partition.html @@ -27,7 +27,7 @@ partition

- + Prototype

@@ -66,7 +66,7 @@

- + Description

@@ -80,14 +80,14 @@ corresponds to the middle iterator.

- + Definition

Defined in the header file boost/range/algorithm/partition.hpp

- + Requirements
    @@ -107,7 +107,7 @@
- + Complexity

diff --git a/doc/html/range/reference/algorithms/mutating/random_shuffle.html b/doc/html/range/reference/algorithms/mutating/random_shuffle.html index f1a3c6c..8b8629d 100644 --- a/doc/html/range/reference/algorithms/mutating/random_shuffle.html +++ b/doc/html/range/reference/algorithms/mutating/random_shuffle.html @@ -27,7 +27,7 @@ random_shuffle

- + Prototype

@@ -48,7 +48,7 @@

- + Description

@@ -60,14 +60,14 @@ the shuffles range.

- + Definition

Defined in the header file boost/range/algorithm/random_shuffle.hpp

- + Requirements

@@ -98,7 +98,7 @@

- + Precondition:
  • @@ -107,7 +107,7 @@ maximum value.
- + Complexity

diff --git a/doc/html/range/reference/algorithms/mutating/remove.html b/doc/html/range/reference/algorithms/mutating/remove.html index 618d087..172fd87 100644 --- a/doc/html/range/reference/algorithms/mutating/remove.html +++ b/doc/html/range/reference/algorithms/mutating/remove.html @@ -27,7 +27,7 @@ remove

- + Prototype

@@ -66,7 +66,7 @@

- + Description

@@ -83,14 +83,14 @@ are dereferenceable, but the elements are unspecified.

- + Definition

Defined in the header file boost/range/algorithm/remove.hpp

- + Requirements
    @@ -113,7 +113,7 @@
- + Complexity

diff --git a/doc/html/range/reference/algorithms/mutating/remove_copy.html b/doc/html/range/reference/algorithms/mutating/remove_copy.html index 410848d..a5aff6b 100644 --- a/doc/html/range/reference/algorithms/mutating/remove_copy.html +++ b/doc/html/range/reference/algorithms/mutating/remove_copy.html @@ -27,7 +27,7 @@ remove_copy

- + Prototype

@@ -44,7 +44,7 @@

- + Description

@@ -53,14 +53,14 @@ rng for which x == val is false.

- + Definition

Defined in the header file boost/range/algorithm/remove_copy.hpp

- + Requirements
    @@ -83,7 +83,7 @@
- + Complexity

diff --git a/doc/html/range/reference/algorithms/mutating/remove_copy_if.html b/doc/html/range/reference/algorithms/mutating/remove_copy_if.html index ed95b13..4763181 100644 --- a/doc/html/range/reference/algorithms/mutating/remove_copy_if.html +++ b/doc/html/range/reference/algorithms/mutating/remove_copy_if.html @@ -27,7 +27,7 @@ remove_copy_if

- + Prototype

@@ -44,7 +44,7 @@

- + Description

@@ -54,14 +54,14 @@ is false.

- + Definition

Defined in the header file boost/range/algorithm/remove_copy_if.hpp

- + Requirements
    @@ -79,7 +79,7 @@
- + Complexity

diff --git a/doc/html/range/reference/algorithms/mutating/remove_if.html b/doc/html/range/reference/algorithms/mutating/remove_if.html index 113d9dd..59aebc2 100644 --- a/doc/html/range/reference/algorithms/mutating/remove_if.html +++ b/doc/html/range/reference/algorithms/mutating/remove_if.html @@ -27,7 +27,7 @@ remove_if

- + Prototype

@@ -66,7 +66,7 @@

- + Description

@@ -82,14 +82,14 @@ are unspecified.

- + Definition

Defined in the header file boost/range/algorithm/remove_if.hpp

- + Requirements
    @@ -112,7 +112,7 @@
- + Complexity

diff --git a/doc/html/range/reference/algorithms/mutating/replace.html b/doc/html/range/reference/algorithms/mutating/replace.html index 9055f9a..b392c50 100644 --- a/doc/html/range/reference/algorithms/mutating/replace.html +++ b/doc/html/range/reference/algorithms/mutating/replace.html @@ -27,7 +27,7 @@ replace

- + Prototype

@@ -48,7 +48,7 @@

- + Description

@@ -57,14 +57,14 @@ Return a reference to rng.

- + Definition

Defined in the header file boost/range/algorithm/replace.hpp

- + Requirements
    @@ -93,7 +93,7 @@
- + Complexity

diff --git a/doc/html/range/reference/algorithms/mutating/replace_copy.html b/doc/html/range/reference/algorithms/mutating/replace_copy.html index 267f594..1784235 100644 --- a/doc/html/range/reference/algorithms/mutating/replace_copy.html +++ b/doc/html/range/reference/algorithms/mutating/replace_copy.html @@ -27,7 +27,7 @@ replace_copy

- + Prototype

@@ -40,7 +40,7 @@

- + Description

@@ -53,14 +53,14 @@ x.

- + Definition

Defined in the header file boost/range/algorithm/replace_copy.hpp

- + Requirements
    @@ -87,7 +87,7 @@
- + Complexity

diff --git a/doc/html/range/reference/algorithms/mutating/replace_copy_if.html b/doc/html/range/reference/algorithms/mutating/replace_copy_if.html index b053c1e..d4d3be2 100644 --- a/doc/html/range/reference/algorithms/mutating/replace_copy_if.html +++ b/doc/html/range/reference/algorithms/mutating/replace_copy_if.html @@ -27,7 +27,7 @@ replace_copy_if

- + Prototype

@@ -40,7 +40,7 @@

- + Description

@@ -51,14 +51,14 @@ : x.

- + Definition

Defined in the header file boost/range/algorithm/replace_copy_if.hpp

- + Requirements
    @@ -89,7 +89,7 @@
- + Complexity

diff --git a/doc/html/range/reference/algorithms/mutating/replace_if.html b/doc/html/range/reference/algorithms/mutating/replace_if.html index f63c30e..1e6609b 100644 --- a/doc/html/range/reference/algorithms/mutating/replace_if.html +++ b/doc/html/range/reference/algorithms/mutating/replace_if.html @@ -27,7 +27,7 @@ replace_if

- + Prototype

@@ -42,7 +42,7 @@

- + Description

@@ -51,14 +51,14 @@ Returns a reference to rng.

- + Definition

Defined in the header file boost/range/algorithm/replace_if.hpp

- + Requirements
    @@ -90,7 +90,7 @@
- + Complexity

diff --git a/doc/html/range/reference/algorithms/mutating/reverse.html b/doc/html/range/reference/algorithms/mutating/reverse.html index 2e8262b..6907fe5 100644 --- a/doc/html/range/reference/algorithms/mutating/reverse.html +++ b/doc/html/range/reference/algorithms/mutating/reverse.html @@ -27,7 +27,7 @@ reverse

- + Prototype

@@ -42,7 +42,7 @@

- + Description

@@ -50,14 +50,14 @@ Returns a reference to the reversed range.

- + Definition

Defined in the header file boost/range/algorithm/reverse.hpp

- + Requirements
    @@ -72,7 +72,7 @@
- + Complexity

diff --git a/doc/html/range/reference/algorithms/mutating/reverse_copy.html b/doc/html/range/reference/algorithms/mutating/reverse_copy.html index ea0d3e9..b0c9624 100644 --- a/doc/html/range/reference/algorithms/mutating/reverse_copy.html +++ b/doc/html/range/reference/algorithms/mutating/reverse_copy.html @@ -27,7 +27,7 @@ reverse_copy

- + Prototype

@@ -39,7 +39,7 @@

- + Description

@@ -49,14 +49,14 @@ Returns the output iterator one passed the last copied element.

- + Definition

Defined in the header file boost/range/algorithm/reverse_copy.hpp

- + Requirements
    @@ -75,7 +75,7 @@
- + Complexity

diff --git a/doc/html/range/reference/algorithms/mutating/rotate.html b/doc/html/range/reference/algorithms/mutating/rotate.html index 4b55abb..de9388a 100644 --- a/doc/html/range/reference/algorithms/mutating/rotate.html +++ b/doc/html/range/reference/algorithms/mutating/rotate.html @@ -27,7 +27,7 @@ rotate

- + Prototype

@@ -44,7 +44,7 @@

- + Description

@@ -53,14 +53,14 @@ and [middle, end(rng)). Returns a reference to rng.

- + Definition

Defined in the header file boost/range/algorithm/rotate.hpp

- + Requirements
    @@ -74,7 +74,7 @@
- + Precondition:
    @@ -86,7 +86,7 @@
- + Complexity

diff --git a/doc/html/range/reference/algorithms/mutating/rotate_copy.html b/doc/html/range/reference/algorithms/mutating/rotate_copy.html index 497fa1d..fbecb94 100644 --- a/doc/html/range/reference/algorithms/mutating/rotate_copy.html +++ b/doc/html/range/reference/algorithms/mutating/rotate_copy.html @@ -27,7 +27,7 @@ rotate_copy

- + Prototype

@@ -42,7 +42,7 @@

- + Description

@@ -51,14 +51,14 @@ and [middle, end(rng)) to out.

- + Definition

Defined in the header file boost/range/algorithm/rotate_copy.hpp

- + Requirements
    @@ -76,7 +76,7 @@
- + Precondition:
    @@ -88,7 +88,7 @@
- + Complexity

diff --git a/doc/html/range/reference/algorithms/mutating/sort.html b/doc/html/range/reference/algorithms/mutating/sort.html index db9444b..aa9512c 100644 --- a/doc/html/range/reference/algorithms/mutating/sort.html +++ b/doc/html/range/reference/algorithms/mutating/sort.html @@ -27,7 +27,7 @@ sort

- + Prototype

@@ -48,7 +48,7 @@

- + Description

@@ -71,14 +71,14 @@ [x,y], pred(y, x) == false.

- + Definition

Defined in the header file boost/range/algorithm/sort.hpp

- + Requirements

@@ -129,7 +129,7 @@

- + Complexity

diff --git a/doc/html/range/reference/algorithms/mutating/stable_partition.html b/doc/html/range/reference/algorithms/mutating/stable_partition.html index bd77f3c..c8dcd45 100644 --- a/doc/html/range/reference/algorithms/mutating/stable_partition.html +++ b/doc/html/range/reference/algorithms/mutating/stable_partition.html @@ -27,7 +27,7 @@ stable_partition

- + Prototype

@@ -60,7 +60,7 @@

- + Description

@@ -82,14 +82,14 @@ the iterator to the first element that fails to satisfy pred.

- + Definition

Defined in the header file boost/range/algorithm/stable_partition.hpp

- + Requirements
    @@ -107,7 +107,7 @@
- + Complexity

diff --git a/doc/html/range/reference/algorithms/mutating/stable_sort.html b/doc/html/range/reference/algorithms/mutating/stable_sort.html index 6196114..e22f262 100644 --- a/doc/html/range/reference/algorithms/mutating/stable_sort.html +++ b/doc/html/range/reference/algorithms/mutating/stable_sort.html @@ -27,7 +27,7 @@ stable_sort

- + Prototype

@@ -48,7 +48,7 @@

- + Description

@@ -71,14 +71,14 @@ [x,y], pred(y,x) == false.

- + Definition

Defined in the header file boost/range/algorithm/stable_sort.hpp

- + Requirements

@@ -129,7 +129,7 @@

- + Complexity

diff --git a/doc/html/range/reference/algorithms/mutating/swap_ranges.html b/doc/html/range/reference/algorithms/mutating/swap_ranges.html index 2e818ce..0e329dd 100644 --- a/doc/html/range/reference/algorithms/mutating/swap_ranges.html +++ b/doc/html/range/reference/algorithms/mutating/swap_ranges.html @@ -27,7 +27,7 @@ swap_ranges

- + Prototype

@@ -39,7 +39,7 @@

- + Description

@@ -49,14 +49,14 @@ Returns a reference to rng2.

- + Definition

Defined in the header file boost/range/algorithm/swap_ranges.hpp

- + Requirements
    @@ -80,7 +80,7 @@
- + Complexity

diff --git a/doc/html/range/reference/algorithms/mutating/transform.html b/doc/html/range/reference/algorithms/mutating/transform.html index 068db05..77a319c 100644 --- a/doc/html/range/reference/algorithms/mutating/transform.html +++ b/doc/html/range/reference/algorithms/mutating/transform.html @@ -27,7 +27,7 @@ transform

- + Prototype

@@ -56,7 +56,7 @@

- + Description

@@ -92,14 +92,14 @@ The return value is out + min(distance(rng1), distance(rng2)).

- + Definition

Defined in the header file boost/range/algorithm/transform.hpp

- + Requirements

@@ -169,7 +169,7 @@

- + Precondition:

@@ -203,7 +203,7 @@

- + Complexity

diff --git a/doc/html/range/reference/algorithms/mutating/unique.html b/doc/html/range/reference/algorithms/mutating/unique.html index e36cbfe..7aa3f2f 100644 --- a/doc/html/range/reference/algorithms/mutating/unique.html +++ b/doc/html/range/reference/algorithms/mutating/unique.html @@ -27,7 +27,7 @@ unique

- + Prototype

@@ -68,7 +68,7 @@

- + Description

@@ -86,14 +86,14 @@ type.

- + Definition

Defined in the header file boost/range/algorithm/unique.hpp

- + Requirements

@@ -137,7 +137,7 @@

- + Complexity

diff --git a/doc/html/range/reference/algorithms/mutating/unique_copy.html b/doc/html/range/reference/algorithms/mutating/unique_copy.html index 432191e..cd4a014 100644 --- a/doc/html/range/reference/algorithms/mutating/unique_copy.html +++ b/doc/html/range/reference/algorithms/mutating/unique_copy.html @@ -27,7 +27,7 @@ unique_copy

- + Prototype

@@ -42,7 +42,7 @@

- + Description

@@ -55,14 +55,14 @@ value type.

- + Definition

Defined in the header file boost/range/algorithm/unique_copy.hpp

- + Requirements

@@ -116,7 +116,7 @@

- + Complexity

diff --git a/doc/html/range/reference/algorithms/new/copy_n.html b/doc/html/range/reference/algorithms/new/copy_n.html index dedfad3..d7ce746 100644 --- a/doc/html/range/reference/algorithms/new/copy_n.html +++ b/doc/html/range/reference/algorithms/new/copy_n.html @@ -27,7 +27,7 @@ copy_n

- + Prototype

@@ -39,7 +39,7 @@

- + Description

@@ -53,14 +53,14 @@ from [boost::begin(rng), boost::begin(rng) + n) to the range [out, out + n)

- + Definition

Defined in the header file boost/range/algorithm_ext/copy_n.hpp

- + Requirements
    @@ -79,7 +79,7 @@
- + Complexity

diff --git a/doc/html/range/reference/algorithms/new/erase.html b/doc/html/range/reference/algorithms/new/erase.html index ef49c5f..dffd697 100644 --- a/doc/html/range/reference/algorithms/new/erase.html +++ b/doc/html/range/reference/algorithms/new/erase.html @@ -27,7 +27,7 @@ erase

- + Prototype

@@ -41,7 +41,7 @@

- + Description

@@ -58,14 +58,14 @@ the frequently used combination equivalent to target.erase(std::remove_if(target.begin(), target.end(), pred), target.end());

- + Definition

Defined in the header file boost/range/algorithm_ext/erase.hpp

- + Requirements
  1. @@ -73,7 +73,7 @@ erase of an iterator range.
- + Complexity

diff --git a/doc/html/range/reference/algorithms/new/for_each.html b/doc/html/range/reference/algorithms/new/for_each.html index 15ec17b..58885de 100644 --- a/doc/html/range/reference/algorithms/new/for_each.html +++ b/doc/html/range/reference/algorithms/new/for_each.html @@ -27,7 +27,7 @@ for_each

- + Prototype

@@ -72,7 +72,7 @@

- + Description

@@ -88,14 +88,14 @@ It is safe to call this function with unequal length ranges.

- + Definition

Defined in the header file boost/range/algorithm_ext/for_each.hpp

- + Requirements
    @@ -125,7 +125,7 @@
- + Complexity

diff --git a/doc/html/range/reference/algorithms/new/insert.html b/doc/html/range/reference/algorithms/new/insert.html index dec9b6a..e702ab7 100644 --- a/doc/html/range/reference/algorithms/new/insert.html +++ b/doc/html/range/reference/algorithms/new/insert.html @@ -27,7 +27,7 @@ insert

- + Prototype

@@ -44,7 +44,7 @@

- + Description

@@ -54,14 +54,14 @@ target.

- + Definition

Defined in the header file boost/range/algorithm_ext/insert.hpp

- + Requirements
    @@ -81,7 +81,7 @@
- + Complexity

diff --git a/doc/html/range/reference/algorithms/new/iota.html b/doc/html/range/reference/algorithms/new/iota.html index b3c8c06..47054f4 100644 --- a/doc/html/range/reference/algorithms/new/iota.html +++ b/doc/html/range/reference/algorithms/new/iota.html @@ -27,7 +27,7 @@ iota

- + Prototype

@@ -39,7 +39,7 @@

- + Description

@@ -50,14 +50,14 @@ + boost::distance(boost::begin(rng), it)

- + Definition

Defined in the header file boost/range/algorithm_ext/iota.hpp

- + Requirements
    @@ -73,7 +73,7 @@
- + Complexity

diff --git a/doc/html/range/reference/algorithms/new/is_sorted.html b/doc/html/range/reference/algorithms/new/is_sorted.html index 93e9ee9..41d6bdc 100644 --- a/doc/html/range/reference/algorithms/new/is_sorted.html +++ b/doc/html/range/reference/algorithms/new/is_sorted.html @@ -27,7 +27,7 @@ is_sorted

- + Prototype

@@ -42,7 +42,7 @@

- + Description

@@ -58,14 +58,14 @@ is true.

- + Definition

Defined in the header file boost/range/algorithm_ext/is_sorted.hpp

- + Requirements
    @@ -85,7 +85,7 @@
- + Complexity

diff --git a/doc/html/range/reference/algorithms/new/overwrite.html b/doc/html/range/reference/algorithms/new/overwrite.html index 914a4e8..7fa22b4 100644 --- a/doc/html/range/reference/algorithms/new/overwrite.html +++ b/doc/html/range/reference/algorithms/new/overwrite.html @@ -27,7 +27,7 @@ overwrite

- + Prototype

@@ -43,7 +43,7 @@

- + Description

@@ -52,14 +52,14 @@ into the range to.

- + Definition

Defined in the header file boost/range/algorithm_ext/overwrite.hpp

- + Requirements
    @@ -88,7 +88,7 @@
- + Complexity

diff --git a/doc/html/range/reference/algorithms/new/push_back.html b/doc/html/range/reference/algorithms/new/push_back.html index 58dd060..a348b93 100644 --- a/doc/html/range/reference/algorithms/new/push_back.html +++ b/doc/html/range/reference/algorithms/new/push_back.html @@ -27,7 +27,7 @@ push_back

- + Prototype

@@ -43,7 +43,7 @@

- + Description

@@ -52,14 +52,14 @@ to the back of the container target.

- + Definition

Defined in the header file boost/range/algorithm_ext/push_back.hpp

- + Requirements
    @@ -79,7 +79,7 @@
- + Complexity

diff --git a/doc/html/range/reference/algorithms/new/push_front.html b/doc/html/range/reference/algorithms/new/push_front.html index 8650468..ab4b48b 100644 --- a/doc/html/range/reference/algorithms/new/push_front.html +++ b/doc/html/range/reference/algorithms/new/push_front.html @@ -27,7 +27,7 @@ push_front

- + Prototype

@@ -43,7 +43,7 @@

- + Description

@@ -52,14 +52,14 @@ to the front of the container target.

- + Definition

Defined in the header file boost/range/algorithm_ext/push_front.hpp

- + Requirements
    @@ -79,7 +79,7 @@
- + Complexity

diff --git a/doc/html/range/reference/algorithms/new/remove_erase.html b/doc/html/range/reference/algorithms/new/remove_erase.html index b28ecfe..e09216b 100644 --- a/doc/html/range/reference/algorithms/new/remove_erase.html +++ b/doc/html/range/reference/algorithms/new/remove_erase.html @@ -27,7 +27,7 @@ remove_erase

- + Prototype

@@ -40,7 +40,7 @@

- + Description

@@ -50,14 +50,14 @@ algorithm which merely rearranges elements.

- + Definition

Defined in the header file boost/range/algorithm_ext/erase.hpp

- + Requirements
  1. @@ -65,7 +65,7 @@ erase of an iterator range.
- + Complexity

diff --git a/doc/html/range/reference/algorithms/new/remove_erase_if.html b/doc/html/range/reference/algorithms/new/remove_erase_if.html index f66b732..bf13441 100644 --- a/doc/html/range/reference/algorithms/new/remove_erase_if.html +++ b/doc/html/range/reference/algorithms/new/remove_erase_if.html @@ -27,7 +27,7 @@ remove_erase_if

- + Prototype

@@ -40,7 +40,7 @@

- + Description

@@ -51,14 +51,14 @@ algorithm which merely rearranges elements.

- + Definition

Defined in the header file boost/range/algorithm_ext/erase.hpp

- + Requirements
    @@ -72,7 +72,7 @@
- + Complexity

diff --git a/doc/html/range/reference/algorithms/non_mutating/adjacent_find.html b/doc/html/range/reference/algorithms/non_mutating/adjacent_find.html index b4e1ec3..d8489ad 100644 --- a/doc/html/range/reference/algorithms/non_mutating/adjacent_find.html +++ b/doc/html/range/reference/algorithms/non_mutating/adjacent_find.html @@ -27,7 +27,7 @@ adjacent_find

- + Prototype

@@ -76,7 +76,7 @@

- + Description

@@ -97,14 +97,14 @@ is true.

- + Definition

Defined in the header file boost/range/algorithm/adjacent_find.hpp

- + Requirements

@@ -142,7 +142,7 @@

- + Complexity

diff --git a/doc/html/range/reference/algorithms/non_mutating/binary_search.html b/doc/html/range/reference/algorithms/non_mutating/binary_search.html index b48a47e..2429e96 100644 --- a/doc/html/range/reference/algorithms/non_mutating/binary_search.html +++ b/doc/html/range/reference/algorithms/non_mutating/binary_search.html @@ -27,7 +27,7 @@ binary_search

- + Prototype

@@ -42,7 +42,7 @@

- + Description

@@ -52,14 +52,14 @@ range rng.

- + Definition

Defined in the header file boost/range/algorithm/binary_search.hpp

- + Requirements

@@ -110,7 +110,7 @@

- + Precondition:

@@ -128,7 +128,7 @@ order according to the function object pred.

- + Complexity

diff --git a/doc/html/range/reference/algorithms/non_mutating/count.html b/doc/html/range/reference/algorithms/non_mutating/count.html index 75b364e..9ce79d3 100644 --- a/doc/html/range/reference/algorithms/non_mutating/count.html +++ b/doc/html/range/reference/algorithms/non_mutating/count.html @@ -27,7 +27,7 @@ count

- + Prototype

@@ -44,7 +44,7 @@

- + Description

@@ -54,14 +54,14 @@ is true.

- + Definition

Defined in the header file boost/range/algorithm/count.hpp

- + Requirements
    @@ -84,7 +84,7 @@
- + Complexity

diff --git a/doc/html/range/reference/algorithms/non_mutating/count_if.html b/doc/html/range/reference/algorithms/non_mutating/count_if.html index b50203b..09b3f05 100644 --- a/doc/html/range/reference/algorithms/non_mutating/count_if.html +++ b/doc/html/range/reference/algorithms/non_mutating/count_if.html @@ -27,7 +27,7 @@ count_if

- + Prototype

@@ -40,7 +40,7 @@

- + Description

@@ -50,14 +50,14 @@ is true.

- + Definition

Defined in the header file boost/range/algorithm/count_if.hpp

- + Requirements
    @@ -80,7 +80,7 @@
- + Complexity

diff --git a/doc/html/range/reference/algorithms/non_mutating/equal.html b/doc/html/range/reference/algorithms/non_mutating/equal.html index d70859b..5b555bb 100644 --- a/doc/html/range/reference/algorithms/non_mutating/equal.html +++ b/doc/html/range/reference/algorithms/non_mutating/equal.html @@ -27,7 +27,7 @@ equal

- + Prototype

@@ -52,7 +52,7 @@

- + Description

@@ -70,14 +70,14 @@ considered equal in the predicate version if pred(x,y) is true.

- + Definition

Defined in the header file boost/range/algorithm/equal.hpp

- + Requirements

@@ -138,7 +138,7 @@

- + Complexity

diff --git a/doc/html/range/reference/algorithms/non_mutating/equal_range.html b/doc/html/range/reference/algorithms/non_mutating/equal_range.html index 0594865..bc8ceb3 100644 --- a/doc/html/range/reference/algorithms/non_mutating/equal_range.html +++ b/doc/html/range/reference/algorithms/non_mutating/equal_range.html @@ -27,7 +27,7 @@ equal_range

- + Prototype

@@ -70,7 +70,7 @@

- + Description

@@ -84,14 +84,14 @@ is determined by pred.

- + Definition

Defined in the header file boost/range/algorithm/equal_range.hpp

- + Requirements

@@ -142,7 +142,7 @@

- + Precondition:

@@ -154,7 +154,7 @@ is ordered in ascending order according to pred.

- + Complexity

diff --git a/doc/html/range/reference/algorithms/non_mutating/find.html b/doc/html/range/reference/algorithms/non_mutating/find.html index 76086a8..0cdb415 100644 --- a/doc/html/range/reference/algorithms/non_mutating/find.html +++ b/doc/html/range/reference/algorithms/non_mutating/find.html @@ -27,7 +27,7 @@ find

- + Prototype

@@ -48,7 +48,7 @@

- + Description

@@ -59,14 +59,14 @@ same manner as the returned iterator described above.

- + Definition

Defined in the header file boost/range/algorithm/find.hpp

- + Requirements
    @@ -87,7 +87,7 @@
- + Complexity

diff --git a/doc/html/range/reference/algorithms/non_mutating/find_end.html b/doc/html/range/reference/algorithms/non_mutating/find_end.html index 95cb212..2381696 100644 --- a/doc/html/range/reference/algorithms/non_mutating/find_end.html +++ b/doc/html/range/reference/algorithms/non_mutating/find_end.html @@ -27,7 +27,7 @@ find_end

- + Prototype

@@ -65,7 +65,7 @@

- + Description

@@ -80,14 +80,14 @@ same manner as the returned iterator described above.

- + Definition

Defined in the header file boost/range/algorithm/find_end.hpp

- + Requirements

@@ -147,7 +147,7 @@

- + Complexity

diff --git a/doc/html/range/reference/algorithms/non_mutating/find_first_of.html b/doc/html/range/reference/algorithms/non_mutating/find_first_of.html index 2751651..6421a4d 100644 --- a/doc/html/range/reference/algorithms/non_mutating/find_first_of.html +++ b/doc/html/range/reference/algorithms/non_mutating/find_first_of.html @@ -27,7 +27,7 @@ find_first_of

- + Prototype

@@ -65,7 +65,7 @@

- + Description

@@ -85,14 +85,14 @@ same manner as the returned iterator described above.

- + Definition

Defined in the header file boost/range/algorithm/find_first_of.hpp

- + Requirements

@@ -146,7 +146,7 @@

- + Complexity

diff --git a/doc/html/range/reference/algorithms/non_mutating/find_if.html b/doc/html/range/reference/algorithms/non_mutating/find_if.html index 18d83c4..836b675 100644 --- a/doc/html/range/reference/algorithms/non_mutating/find_if.html +++ b/doc/html/range/reference/algorithms/non_mutating/find_if.html @@ -27,7 +27,7 @@ find_if

- + Prototype

@@ -48,7 +48,7 @@

- + Description

@@ -63,14 +63,14 @@ defines found in the same manner as the returned iterator described above.

- + Definition

Defined in the header file boost/range/algorithm/find_if.hpp

- + Requirements
    @@ -89,7 +89,7 @@
- + Precondition:

@@ -97,7 +97,7 @@ rng, *i is in the domain of UnaryPredicate.

- + Complexity

diff --git a/doc/html/range/reference/algorithms/non_mutating/for_each.html b/doc/html/range/reference/algorithms/non_mutating/for_each.html index b7f8384..daa7ec1 100644 --- a/doc/html/range/reference/algorithms/non_mutating/for_each.html +++ b/doc/html/range/reference/algorithms/non_mutating/for_each.html @@ -27,7 +27,7 @@ for_each

- + Prototype

@@ -48,7 +48,7 @@

- + Description

@@ -58,14 +58,14 @@ fun(x).

- + Definition

Defined in the header file boost/range/algorithm/for_each.hpp

- + Requirements
    @@ -89,7 +89,7 @@
- + Complexity

diff --git a/doc/html/range/reference/algorithms/non_mutating/lexicographical_compare.html b/doc/html/range/reference/algorithms/non_mutating/lexicographical_compare.html index 25ace1b..704296a 100644 --- a/doc/html/range/reference/algorithms/non_mutating/lexicographical_compare.html +++ b/doc/html/range/reference/algorithms/non_mutating/lexicographical_compare.html @@ -27,7 +27,7 @@ lexicographical_compare

- + Prototype

@@ -52,7 +52,7 @@

- + Description

@@ -72,14 +72,14 @@ predicate versions.

- + Definition

Defined in the header file boost/range/algorithm/lexicographical_compare.hpp

- + Requirements

@@ -144,7 +144,7 @@

- + Complexity

diff --git a/doc/html/range/reference/algorithms/non_mutating/lower_bound.html b/doc/html/range/reference/algorithms/non_mutating/lower_bound.html index b4419b1..b74ddd7 100644 --- a/doc/html/range/reference/algorithms/non_mutating/lower_bound.html +++ b/doc/html/range/reference/algorithms/non_mutating/lower_bound.html @@ -27,7 +27,7 @@ lower_bound

- + Prototype

@@ -48,7 +48,7 @@

- + Description

@@ -71,14 +71,14 @@ same manner as the returned iterator described above.

- + Definition

Defined in the header file boost/range/algorithm/lower_bound.hpp

- + Requirements

@@ -129,7 +129,7 @@

- + Precondition:

@@ -147,7 +147,7 @@ order according to pred.

- + Complexity

diff --git a/doc/html/range/reference/algorithms/non_mutating/max_element.html b/doc/html/range/reference/algorithms/non_mutating/max_element.html index 7202da9..52f7c53 100644 --- a/doc/html/range/reference/algorithms/non_mutating/max_element.html +++ b/doc/html/range/reference/algorithms/non_mutating/max_element.html @@ -27,7 +27,7 @@ max_element

- + Prototype

@@ -83,7 +83,7 @@

- + Description

@@ -97,14 +97,14 @@ same manner as the returned iterator described above.

- + Definition

Defined in the header file boost/range/algorithm/max_element.hpp

- + Requirements

@@ -141,7 +141,7 @@

- + Complexity

diff --git a/doc/html/range/reference/algorithms/non_mutating/min_element.html b/doc/html/range/reference/algorithms/non_mutating/min_element.html index 50260c5..26cd301 100644 --- a/doc/html/range/reference/algorithms/non_mutating/min_element.html +++ b/doc/html/range/reference/algorithms/non_mutating/min_element.html @@ -27,7 +27,7 @@ min_element

- + Prototype

@@ -83,7 +83,7 @@

- + Description

@@ -97,14 +97,14 @@ same manner as the returned iterator described above.

- + Definition

Defined in the header file boost/range/algorithm/min_element.hpp

- + Requirements

@@ -141,7 +141,7 @@

- + Complexity

diff --git a/doc/html/range/reference/algorithms/non_mutating/mismatch.html b/doc/html/range/reference/algorithms/non_mutating/mismatch.html index 30f2acd..cbfad8a 100644 --- a/doc/html/range/reference/algorithms/non_mutating/mismatch.html +++ b/doc/html/range/reference/algorithms/non_mutating/mismatch.html @@ -27,7 +27,7 @@ mismatch

- + Prototype

@@ -105,7 +105,7 @@

- + Description

@@ -117,14 +117,14 @@ Equality is determined by operator== for non-predicate versions of mismatch, and by satisfying pred in the predicate versions.

- + Definition

Defined in the header file boost/range/algorithm/mismatch.hpp

- + Requirements

@@ -185,14 +185,14 @@

- + Precondition:

distance(rng2) >= distance(rng1)

- + Complexity

diff --git a/doc/html/range/reference/algorithms/non_mutating/search.html b/doc/html/range/reference/algorithms/non_mutating/search.html index 6e68396..427642b 100644 --- a/doc/html/range/reference/algorithms/non_mutating/search.html +++ b/doc/html/range/reference/algorithms/non_mutating/search.html @@ -27,7 +27,7 @@ search

- + Prototype

@@ -95,7 +95,7 @@

- + Description

@@ -114,14 +114,14 @@ same manner as the returned iterator described above.

- + Definition

Defined in the header file boost/range/algorithm/search.hpp

- + Requirements

@@ -182,7 +182,7 @@

- + Complexity

diff --git a/doc/html/range/reference/algorithms/non_mutating/search_n.html b/doc/html/range/reference/algorithms/non_mutating/search_n.html index aa1e621..6bc149d 100644 --- a/doc/html/range/reference/algorithms/non_mutating/search_n.html +++ b/doc/html/range/reference/algorithms/non_mutating/search_n.html @@ -27,7 +27,7 @@ search_n

- + Prototype

@@ -54,7 +54,7 @@

- + Description

@@ -63,14 +63,14 @@ and by a predicate when one is supplied.

- + Definition

Defined in the header file boost/range/algorithm/search_n.hpp

- + Requirements

@@ -124,7 +124,7 @@

- + Complexity

diff --git a/doc/html/range/reference/algorithms/non_mutating/upper_bound.html b/doc/html/range/reference/algorithms/non_mutating/upper_bound.html index 6e75ef7..7c5b03e 100644 --- a/doc/html/range/reference/algorithms/non_mutating/upper_bound.html +++ b/doc/html/range/reference/algorithms/non_mutating/upper_bound.html @@ -27,7 +27,7 @@ upper_bound

- + Prototype

@@ -48,7 +48,7 @@

- + Description

@@ -70,14 +70,14 @@ same manner as the returned iterator described above.

- + Definition

Defined in the header file boost/range/algorithm/upper_bound.hpp

- + Requirements

@@ -128,7 +128,7 @@

- + Precondition:

@@ -146,7 +146,7 @@ order according to pred.

- + Complexity

diff --git a/doc/html/range/reference/algorithms/numeric/accumulate.html b/doc/html/range/reference/algorithms/numeric/accumulate.html index e3accc8..a98dc0f 100644 --- a/doc/html/range/reference/algorithms/numeric/accumulate.html +++ b/doc/html/range/reference/algorithms/numeric/accumulate.html @@ -27,7 +27,7 @@ accumulate

- + Prototype

@@ -52,7 +52,7 @@

- + Description

@@ -63,18 +63,18 @@ The return value is the resultant value of the above algorithm.

- + Definition

Defined in the header file boost/range/numeric.hpp

- + Requirements
- + For the first version
@@ -99,7 +99,7 @@
- + For the second version
@@ -133,7 +133,7 @@
- + Complexity

diff --git a/doc/html/range/reference/algorithms/numeric/adjacent_difference.html b/doc/html/range/reference/algorithms/numeric/adjacent_difference.html index b5b3f49..c704d2a 100644 --- a/doc/html/range/reference/algorithms/numeric/adjacent_difference.html +++ b/doc/html/range/reference/algorithms/numeric/adjacent_difference.html @@ -27,7 +27,7 @@ adjacent_difference

- + Prototype

@@ -54,7 +54,7 @@

- + Description

@@ -68,18 +68,18 @@ instead of operator-().

- + Definition

Defined in the header file boost/range/numeric.hpp

- + Requirements
- + For the first version
@@ -110,7 +110,7 @@
- + For the second version
@@ -145,7 +145,7 @@
- + Precondition:

@@ -153,7 +153,7 @@ + distance(rng)) is a valid range.

- + Complexity

diff --git a/doc/html/range/reference/algorithms/numeric/inner_product.html b/doc/html/range/reference/algorithms/numeric/inner_product.html index 9567a89..bebd578 100644 --- a/doc/html/range/reference/algorithms/numeric/inner_product.html +++ b/doc/html/range/reference/algorithms/numeric/inner_product.html @@ -27,7 +27,7 @@ inner_product

- + Prototype

@@ -53,7 +53,7 @@

- + Description

@@ -66,18 +66,18 @@ algorithm please see inner_product.

- + Definition

Defined in the header file boost/range/numeric.hpp

- + Requirements
- + For the first version
@@ -112,7 +112,7 @@
- + For the second version
@@ -161,14 +161,14 @@
- + Precondition:

distance(rng2) >= distance(rng1) is a valid range.

- + Complexity

diff --git a/doc/html/range/reference/algorithms/numeric/partial_sum.html b/doc/html/range/reference/algorithms/numeric/partial_sum.html index 50fa44b..68accc1 100644 --- a/doc/html/range/reference/algorithms/numeric/partial_sum.html +++ b/doc/html/range/reference/algorithms/numeric/partial_sum.html @@ -27,7 +27,7 @@ partial_sum

- + Prototype

@@ -48,7 +48,7 @@

- + Description

@@ -57,18 +57,18 @@ in the same manner as std::partial_sum(boost::begin(rng), boost::end(rng), out_it). See partial_sum.

- + Definition

Defined in the header file boost/range/numeric.hpp

- + Requirements
- + For the first version
@@ -98,7 +98,7 @@
- + For the second version
@@ -127,7 +127,7 @@
- + Precondition:

@@ -135,7 +135,7 @@ + distance(rng)) is a valid range.

- + Complexity

diff --git a/doc/html/range/reference/algorithms/permutation/next_permutation.html b/doc/html/range/reference/algorithms/permutation/next_permutation.html index 78626e7..1f30391 100644 --- a/doc/html/range/reference/algorithms/permutation/next_permutation.html +++ b/doc/html/range/reference/algorithms/permutation/next_permutation.html @@ -27,7 +27,7 @@ next_permutation

- + Prototype

@@ -48,7 +48,7 @@

- + Description

@@ -66,14 +66,14 @@ the predicate versions.

- + Definition

Defined in the header file boost/range/algorithm/permutation.hpp

- + Requirements

@@ -124,7 +124,7 @@

- + Complexity

diff --git a/doc/html/range/reference/algorithms/permutation/prev_permutation.html b/doc/html/range/reference/algorithms/permutation/prev_permutation.html index c87dadb..c43900a 100644 --- a/doc/html/range/reference/algorithms/permutation/prev_permutation.html +++ b/doc/html/range/reference/algorithms/permutation/prev_permutation.html @@ -27,7 +27,7 @@ prev_permutation

- + Prototype

@@ -48,7 +48,7 @@

- + Description

@@ -66,14 +66,14 @@ the predicate versions.

- + Definition

Defined in the header file boost/range/algorithm/permutation.hpp

- + Requirements

@@ -124,7 +124,7 @@

- + Complexity

diff --git a/doc/html/range/reference/algorithms/set/includes.html b/doc/html/range/reference/algorithms/set/includes.html index 9090779..9baedb3 100644 --- a/doc/html/range/reference/algorithms/set/includes.html +++ b/doc/html/range/reference/algorithms/set/includes.html @@ -27,7 +27,7 @@ includes

- + Prototype

@@ -47,7 +47,7 @@

- + Description

@@ -59,14 +59,14 @@ the predicate versions.

- + Definition

Defined in the header file boost/range/algorithm/set_algorithm.hpp

- + Requirements

@@ -144,7 +144,7 @@

- + Precondition:

@@ -162,7 +162,7 @@ according to pred.

- + Complexity

diff --git a/doc/html/range/reference/algorithms/set/set_difference.html b/doc/html/range/reference/algorithms/set/set_difference.html index 6aa68d8..7712445 100644 --- a/doc/html/range/reference/algorithms/set/set_difference.html +++ b/doc/html/range/reference/algorithms/set/set_difference.html @@ -27,7 +27,7 @@ set_difference

- + Prototype

@@ -56,7 +56,7 @@

- + Description

@@ -70,14 +70,14 @@ the predicate versions.

- + Definition

Defined in the header file boost/range/algorithm/set_algorithm.hpp

- + Requirements

@@ -163,7 +163,7 @@

- + Precondition:

@@ -181,7 +181,7 @@ according to pred.

- + Complexity

diff --git a/doc/html/range/reference/algorithms/set/set_intersection.html b/doc/html/range/reference/algorithms/set/set_intersection.html index 0c4705e..1a2040d 100644 --- a/doc/html/range/reference/algorithms/set/set_intersection.html +++ b/doc/html/range/reference/algorithms/set/set_intersection.html @@ -27,7 +27,7 @@ set_intersection

- + Prototype

@@ -56,7 +56,7 @@

- + Description

@@ -70,14 +70,14 @@ the predicate versions.

- + Definition

Defined in the header file boost/range/algorithm/set_algorithm.hpp

- + Requirements

@@ -163,7 +163,7 @@

- + Precondition:

@@ -181,7 +181,7 @@ according to pred.

- + Complexity

diff --git a/doc/html/range/reference/algorithms/set/set_symmetric_difference.html b/doc/html/range/reference/algorithms/set/set_symmetric_difference.html index aab6c38..215facc 100644 --- a/doc/html/range/reference/algorithms/set/set_symmetric_difference.html +++ b/doc/html/range/reference/algorithms/set/set_symmetric_difference.html @@ -27,7 +27,7 @@ set_symmetric_difference

- + Prototype

@@ -58,7 +58,7 @@

- + Description

@@ -74,14 +74,14 @@ the predicate versions.

- + Definition

Defined in the header file boost/range/algorithm/set_algorithm.hpp

- + Requirements

@@ -167,7 +167,7 @@

- + Precondition:

@@ -185,7 +185,7 @@ according to pred.

- + Complexity

diff --git a/doc/html/range/reference/algorithms/set/set_union.html b/doc/html/range/reference/algorithms/set/set_union.html index f89ab11..5dc5176 100644 --- a/doc/html/range/reference/algorithms/set/set_union.html +++ b/doc/html/range/reference/algorithms/set/set_union.html @@ -27,7 +27,7 @@ set_union

- + Prototype

@@ -56,7 +56,7 @@

- + Description

@@ -69,14 +69,14 @@ in the predicate versions.

- + Definition

Defined in the header file boost/range/algorithm/set_algorithm.hpp

- + Requirements

@@ -162,7 +162,7 @@

- + Precondition:

@@ -180,7 +180,7 @@ according to pred.

- + Complexity

diff --git a/doc/html/range/reference/concept_implementation/semantics.html b/doc/html/range/reference/concept_implementation/semantics.html index 10f57ad..0aed2fa 100644 --- a/doc/html/range/reference/concept_implementation/semantics.html +++ b/doc/html/range/reference/concept_implementation/semantics.html @@ -31,7 +31,7 @@

Functions
- + notation
diff --git a/doc/html/range/reference/concept_implementation/semantics/functions.html b/doc/html/range/reference/concept_implementation/semantics/functions.html index 318dec3..55f8a17 100644 --- a/doc/html/range/reference/concept_implementation/semantics/functions.html +++ b/doc/html/range/reference/concept_implementation/semantics/functions.html @@ -168,27 +168,10 @@

- The size - of the - range with - complexity O(1). For - RandomAccessRanges this is - achieved via - boost::end(x) - - boost::begin(x). For - other traversal - categories range_calculate_size(x) is - returned. - Note that - unless range_calculate_size(x) has - been implemented - by the - user as - an extension - then the - Argument Dependent - Lookup will - return x.size() + range_calculate_size(x) which by default is boost::end(x) + - boost::begin(x). Users may supply alternative + implementations by implementing range_calculate_size(x) so that it will be found via + ADL

diff --git a/doc/html/range/reference/ranges.html b/doc/html/range/reference/ranges.html index 7ebd43e..37919c5 100644 --- a/doc/html/range/reference/ranges.html +++ b/doc/html/range/reference/ranges.html @@ -7,7 +7,7 @@ - + @@ -20,13 +20,14 @@

-PrevUpHomeNext +PrevUpHomeNext

-PrevUpHomeNext +PrevUpHomeNext
diff --git a/doc/html/range/reference/ranges/any_range.html b/doc/html/range/reference/ranges/any_range.html new file mode 100644 index 0000000..3659c9e --- /dev/null +++ b/doc/html/range/reference/ranges/any_range.html @@ -0,0 +1,177 @@ + + + +any_range + + + + + + + + + + + + + + + +
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ +
+ + Description +
+

+ any_range is a range that + has the type information erased hence a any_range<int, boost::forward_pass_traversal_tag, int, + std::ptrdiff_t> + can be used to represent a std::vector<int>, a std::list<int> or many other types. +

+

+ The type + erasure article covers the motivation and goals of type erasure + in this context. Clearly my implementation is building upon a lot of prior + art created by others. Thomas Becker's any_iterator + was a strong influence. Adobe also have an any_iterator + implementation, but this has very tight coupling to other parts of the + library that precluded it from use in Boost.Range. Early development versions + of this Range Adaptor directly used Thomas Becker's any_iterator implementation. + Subsequently I discovered that the heap allocations of this and many other + implementations cause poor speed performance particularly at the tails + of the distribution. To solve this required a new design that incorporated + the embedded buffer optimization. +

+

+ Despite the underlying any_iterator + being the fastest available implementation, the performance overhead of + any_range is still appreciable + due to the cost of virtual function calls required to implement increment, decrement, + advance, equal etc. Frequently a better design + choice is to convert to a canonical form. +

+

+ Please see the type_erased + for a Range Adaptor that returns any_range + instances. +

+
+ + Synopsis +
+

+ +

+
template<
+    class Value
+  , class Traversal
+  , class Reference
+  , class Difference
+  , class Buffer = any_iterator_default_buffer
+>
+class any_range
+    : public iterator_range<
+        range_detail::any_iterator<
+            Value
+          , Traversal
+          , Reference
+          , Difference
+          , Buffer
+        >
+    >
+{
+    typedef range_detail::any_iterator<
+        Value
+      , Traversal
+      , Reference
+      , Difference
+      , Buffer
+    > any_iterator_type;
+
+    typedef iterator_range<any_iterator_type> base_type;
+
+    struct enabler {};
+    struct disabler {};
+public:
+    typedef any_iterator_type iterator;
+    typedef any_iterator_type const_iterator;
+
+    any_range()
+    {
+    }
+
+    any_range(const any_range& other)
+        : base_type(other)
+    {
+    }
+
+    template<class WrappedRange>
+    any_range(WrappedRange& wrapped_range)
+    : base_type(boost::begin(wrapped_range),
+                boost::end(wrapped_range))
+    {
+    }
+
+    template<class WrappedRange>
+    any_range(const WrappedRange& wrapped_range)
+    : base_type(boost::begin(wrapped_range),
+                boost::end(wrapped_range))
+    {
+    }
+
+    template<
+        class OtherValue
+      , class OtherTraversal
+      , class OtherReference
+      , class OtherDifference
+    >
+    any_range(const any_range<
+                        OtherValue
+                      , OtherTraversal
+                      , OtherReference
+                      , OtherDifference
+                      , Buffer
+                    >& other)
+    : base_type(boost::begin(other), boost::end(other))
+    {
+    }
+
+    template<class Iterator>
+    any_range(Iterator first, Iterator last)
+        : base_type(first, last)
+    {
+    }
+};
+
+

+

+
+ + Definition +
+

+ Defined in header file boost/range/any_range.hpp +

+
+ + + +
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/range/reference/ranges/counting_range.html b/doc/html/range/reference/ranges/counting_range.html index 01355b0..21a8a16 100644 --- a/doc/html/range/reference/ranges/counting_range.html +++ b/doc/html/range/reference/ranges/counting_range.html @@ -6,7 +6,7 @@ - + @@ -20,14 +20,14 @@
-PrevUpHomeNext +PrevUpHomeNext
- + Prototype

@@ -48,7 +48,7 @@

- + Description

@@ -58,14 +58,14 @@ (from Boost.Iterator).

- + Definition

Defined in header file boost/range/counting_range.hpp

- + Requirements
  1. @@ -84,7 +84,7 @@
    -PrevUpHomeNext +PrevUpHomeNext
    diff --git a/doc/html/range/reference/ranges/irange.html b/doc/html/range/reference/ranges/irange.html index 291a416..6cc143c 100644 --- a/doc/html/range/reference/ranges/irange.html +++ b/doc/html/range/reference/ranges/irange.html @@ -27,7 +27,7 @@ irange
- + Prototype

@@ -44,7 +44,7 @@

- + Description

@@ -58,14 +58,14 @@ parameters denoted a half-open range.

- + Definition

Defined in the header file boost/range/irange.hpp

- + Requirements
    @@ -80,7 +80,7 @@
- + Complexity

diff --git a/doc/html/range/reference/ranges/istream_range.html b/doc/html/range/reference/ranges/istream_range.html index 3e704f2..8b11dde 100644 --- a/doc/html/range/reference/ranges/istream_range.html +++ b/doc/html/range/reference/ranges/istream_range.html @@ -27,7 +27,7 @@ istream_range

- + Prototype

@@ -40,7 +40,7 @@

- + Description

@@ -49,7 +49,7 @@ wrapping a std::istream_iterator.

- + Definition

diff --git a/doc/html/range/reference/utilities/iterator_range.html b/doc/html/range/reference/utilities/iterator_range.html index b2b1923..bbe4521 100644 --- a/doc/html/range/reference/utilities/iterator_range.html +++ b/doc/html/range/reference/utilities/iterator_range.html @@ -48,7 +48,7 @@ type.

- + Synopsis

@@ -188,7 +188,7 @@ iterators from the same container.

- + Details member functions
@@ -207,7 +207,7 @@ == r.end();

- + Details functions
diff --git a/doc/html/range/reference/utilities/join.html b/doc/html/range/reference/utilities/join.html index 8fc0d82..6b7d849 100644 --- a/doc/html/range/reference/utilities/join.html +++ b/doc/html/range/reference/utilities/join.html @@ -39,7 +39,7 @@ check if the end of a range has been reached internally during traversal.

- + Synposis

@@ -108,7 +108,7 @@

- + Example

diff --git a/doc/html/range/reference/utilities/sub_range.html b/doc/html/range/reference/utilities/sub_range.html index e82e7f5..c35e707 100644 --- a/doc/html/range/reference/utilities/sub_range.html +++ b/doc/html/range/reference/utilities/sub_range.html @@ -35,7 +35,7 @@ is.

- + Synopsis

diff --git a/doc/reference/adaptors.qbk b/doc/reference/adaptors.qbk index 260fc39..91401c0 100644 --- a/doc/reference/adaptors.qbk +++ b/doc/reference/adaptors.qbk @@ -177,6 +177,7 @@ rng | boost::adaptors::adaptor_generator [include adaptors/reversed.qbk] [include adaptors/sliced.qbk] [include adaptors/strided.qbk] +[include adaptors/type_erased.qbk] [include adaptors/tokenized.qbk] [include adaptors/transformed.qbk] [include adaptors/uniqued.qbk] diff --git a/doc/reference/adaptors/strided.qbk b/doc/reference/adaptors/strided.qbk index 0f57222..e219a83 100644 --- a/doc/reference/adaptors/strided.qbk +++ b/doc/reference/adaptors/strided.qbk @@ -11,7 +11,7 @@ [[Function] [`boost::adaptors::stride(rng, n)`]] ] -* [*Precondition:] `0 <= n` and `boost::size(rng)` is a valid expression. +* [*Precondition:] `0 <= n`. * [*Returns:] A new range based on `rng` where traversal is performed in steps of `n`. * [*Range Category:] __single_pass_range__ * [*Returned Range Category:] The range category of `rng`. diff --git a/doc/reference/adaptors/type_erased.qbk b/doc/reference/adaptors/type_erased.qbk new file mode 100644 index 0000000..a24bee7 --- /dev/null +++ b/doc/reference/adaptors/type_erased.qbk @@ -0,0 +1,151 @@ +[/ + Copyright 2010 Neil Groves + 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) +/] +[section:type_erased type_erased] + +[table + [[Syntax] [Code]] + [[Pipe] [`rng | boost::adaptors::type_erased()`]] + [[Function] [`boost::adaptors::type_erase(rng, boost::adaptors::type_erased)`]] +] + +Please note that it is frequently unnecessary to use the `type_erased` adaptor. It is often better to use the implicit conversion to `any_range`. + +Let `Rng` be the type of `rng`. + +* [*Template parameters:] + * `Value` is the `value_type` for the `any_range`. If this is set to boost::use_default, `Value` will be calculated from the + range type when the adaptor is applied. + * `Traversal` is the tag used to identify the traversal of the resultant range. Frequently it is desireable to set a traversal category lower than the source container or range to maximize the number of ranges that can convert to the `any_range`. If this is left as boost::use_default then `Traversal` will be `typename boost::iterator_traversal::type>::type` + * `Reference` is the `reference` for the `any_range`. `boost::use_default` will equate to `typename range_reference::type`. + * `Difference` is the `difference_type` for the any_range. `boost::use_default` will equate to `typename boost::range_difference::type` + * `Buffer` is the storage used to allocate the underlying iterator wrappers. This can typically be ignored, but is available as a template parameter for customization. Buffer must be a model of the `AnyIteratorBufferConcept`. +* [*Precondition:] `Traversal` is one of `{ boost::use_default, boost::single_pass_traversal_tag, boost::forward_traversal_tag, boost::bidirectional_traversal_tag, boost::random_access_traversal_tag }` +* [*Returns:] The returned value is the same as `typename any_range_type_generator< Rng, Value, Traversal, Reference, Difference, Buffer >` that represents `rng` in a type-erased manner. +* [*Range Category:] __single_pass_range__ +* [*Returned Range Category:] if `Traversal` was specified as `boost::use_default` then `typename boost::iterator_traversal::type>::type`, otherwise `Traversal`. + +[heading AnyIteratorBufferConcept] +`` +class AnyIteratorBufferConcept +{ +public: + AnyIteratorBufferConcept(); + ~AnyIteratorBufferConcept(); + + // bytes is the requested size to allocate. This function + // must return a pointer to an adequate area of memory. + // throws: bad_alloc + // + // The buffer will only ever have zero or one + // outstanding memory allocations. + void* allocate(std::size_t bytes); + + // deallocate this buffer + void deallocate(); +}; +`` + +[section:type_erased_example type-erased example] +`` +#include +#include +#include +#include +#include +#include +#include +#include + +// The client interface from an OO perspective merely requires a sequence +// of integers that can be forward traversed +typedef boost::any_range< + int + , boost::forward_traversal_tag + , int + , std::ptrdiff_t +> integer_range; + +namespace server +{ + void display_integers(const integer_range& rng) + { + boost::copy(rng, + std::ostream_iterator(std::cout, ",")); + + std::cout << std::endl; + } +} + +namespace client +{ + void run() + { + using namespace boost::assign; + using namespace boost::adaptors; + + // Under most conditions one would simply use an appropriate + // any_range as a function parameter. The type_erased adaptor + // is often superfluous. However because the type_erased + // adaptor is applied to a range, we can use default template + // arguments that are generated in conjunction with the + // range type to which we are applying the adaptor. + + std::vector input; + input += 1,2,3,4,5; + + // Note that this call is to a non-template function + server::display_integers(input); + + std::list input2; + input2 += 6,7,8,9,10; + + // Note that this call is to the same non-tempate function + server::display_integers(input2); + + input2.clear(); + input2 += 11,12,13,14,15; + + // Calling using the adaptor looks like this: + // Notice that here I have a type_erased that would be a + // bidirectional_traversal_tag, but this is convertible + // to the forward_traversal_tag equivalent hence this + // works. + server::display_integers(input2 | type_erased<>()); + + // However we may simply wish to define an adaptor that + // takes a range and makes it into an appropriate + // forward_traversal any_range... + typedef boost::adaptors::type_erased< + boost::use_default + , boost::forward_traversal_tag + > type_erased_forward; + + // This adaptor can turn other containers with different + // value_types and reference_types into the appropriate + // any_range. + + server::display_integers(input2 | type_erased_forward()); + } +} + +int main(int argc, const char* argv[]) +{ + client::run(); + return 0; +} +`` +[endsect] + +This would produce the output: +`` +1,2,3,4,5 +6,7,8,9,10 +11,12,13,14,15 +11,12,13,14,15 +`` +[endsect] + + diff --git a/doc/reference/ranges.qbk b/doc/reference/ranges.qbk index 14299c4..5b853d5 100644 --- a/doc/reference/ranges.qbk +++ b/doc/reference/ranges.qbk @@ -5,6 +5,7 @@ /] [section:ranges Provided Ranges] +[include ranges/any_range.qbk] [include ranges/counting_range.qbk] [include ranges/istream_range.qbk] [include ranges/irange.qbk] diff --git a/doc/reference/ranges/any_range.qbk b/doc/reference/ranges/any_range.qbk new file mode 100644 index 0000000..6ff224e --- /dev/null +++ b/doc/reference/ranges/any_range.qbk @@ -0,0 +1,115 @@ +[/ + Copyright 2010 Neil Groves + 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) +/] +[section:any_range any_range] + +[heading Description] + +`any_range` is a range that has the type information erased hence a `any_range` +can be used to represent a `std::vector`, a `std::list` or many other types. + +The __type_erasure_article__ covers the motivation and goals of type erasure in this context. Clearly +my implementation is building upon a lot of prior art created by others. Thomas Becker's `any_iterator` was a strong +influence. Adobe also have an `any_iterator` implementation, but this has very tight coupling to other parts of the +library that precluded it from use in Boost.Range. +Early development versions of this Range Adaptor directly used Thomas Becker's any_iterator implementation. +Subsequently I discovered that the heap allocations of this and many other implementations cause poor +speed performance particularly at the tails of the distribution. To solve this required a new design that +incorporated the embedded buffer optimization. + +Despite the underlying `any_iterator` being the fastest available implementation, the performance overhead of `any_range` is still appreciable due to the cost of virtual function calls required to implement `increment`, `decrement`, `advance`, `equal` etc. Frequently a better design choice is to convert to a canonical form. + +Please see the __range_adaptors_type_erased__ for a Range Adaptor that returns `any_range` instances. + +[heading Synopsis] + +`` +template< + class Value + , class Traversal + , class Reference + , class Difference + , class Buffer = any_iterator_default_buffer +> +class any_range + : public iterator_range< + range_detail::any_iterator< + Value + , Traversal + , Reference + , Difference + , Buffer + > + > +{ + typedef range_detail::any_iterator< + Value + , Traversal + , Reference + , Difference + , Buffer + > any_iterator_type; + + typedef iterator_range base_type; + + struct enabler {}; + struct disabler {}; +public: + typedef any_iterator_type iterator; + typedef any_iterator_type const_iterator; + + any_range() + { + } + + any_range(const any_range& other) + : base_type(other) + { + } + + template + any_range(WrappedRange& wrapped_range) + : base_type(boost::begin(wrapped_range), + boost::end(wrapped_range)) + { + } + + template + any_range(const WrappedRange& wrapped_range) + : base_type(boost::begin(wrapped_range), + boost::end(wrapped_range)) + { + } + + template< + class OtherValue + , class OtherTraversal + , class OtherReference + , class OtherDifference + > + any_range(const any_range< + OtherValue + , OtherTraversal + , OtherReference + , OtherDifference + , Buffer + >& other) + : base_type(boost::begin(other), boost::end(other)) + { + } + + template + any_range(Iterator first, Iterator last) + : base_type(first, last) + { + } +}; +`` + +[heading Definition] + +Defined in header file `boost/range/any_range.hpp` + +[endsect] diff --git a/doc/reference/semantics.qbk b/doc/reference/semantics.qbk index 6276e9d..335ab90 100644 --- a/doc/reference/semantics.qbk +++ b/doc/reference/semantics.qbk @@ -21,7 +21,7 @@ [table [[Expression] [Return type] [Complexity]] [ - [`range_iterator::type`] + [`range_iterator::type`] [`` T::iterator P::first_type @@ -129,7 +129,7 @@ [ [`size(x)`] [`range_difference::type`] - [`The size of the range with complexity O(1). For RandomAccessRanges this is achieved via boost::end(x) - boost::begin(x). For other traversal categories range_calculate_size(x) is returned. Note that unless range_calculate_size(x) has been implemented by the user as an extension then the Argument Dependent Lookup will return x.size()`] + [`range_calculate_size(x)` which by default is `boost::end(x) - boost::begin(x)`. Users may supply alternative implementations by implementing `range_calculate_size(x)` so that it will be found via ADL] [constant time] ] [ diff --git a/include/boost/range/adaptor/sliced.hpp b/include/boost/range/adaptor/sliced.hpp index 7772bb5..14ad986 100755 --- a/include/boost/range/adaptor/sliced.hpp +++ b/include/boost/range/adaptor/sliced.hpp @@ -76,6 +76,7 @@ namespace boost } } // namespace adaptors + using adaptors::sliced_range; } // namespace boost #endif diff --git a/include/boost/range/adaptor/strided.hpp b/include/boost/range/adaptor/strided.hpp index 9bbd8ca..abfad5e 100755 --- a/include/boost/range/adaptor/strided.hpp +++ b/include/boost/range/adaptor/strided.hpp @@ -16,156 +16,287 @@ #include #include -#include - namespace boost { namespace range_detail { - - template + // strided_iterator for wrapping a forward traversal iterator + template class strided_iterator : public iterator_adaptor< - strided_iterator + strided_iterator , BaseIterator + , use_default + , boost::forward_traversal_tag > { - friend class iterator_core_access; + friend class ::boost::iterator_core_access; - typedef iterator_adaptor, BaseIterator> super_t; + typedef iterator_adaptor< + strided_iterator + , BaseIterator + , use_default + , boost::forward_traversal_tag + > super_t; public: typedef BOOST_DEDUCED_TYPENAME std::iterator_traits::difference_type difference_type; + typedef BaseIterator base_iterator; strided_iterator() - : m_stride(), m_offset(), m_max_offset() + : m_last() + , m_stride() { } - explicit strided_iterator(BaseIterator base_it, - difference_type stride, - difference_type offset, - difference_type max_offset) - : super_t(base_it) + strided_iterator(base_iterator first, base_iterator it, base_iterator last, difference_type stride) + : super_t(it) + , m_last(last) , m_stride(stride) - , m_offset(offset) - , m_max_offset(max_offset) { } template - strided_iterator(const strided_iterator& other, - BOOST_DEDUCED_TYPENAME enable_if_convertible::type* = 0) + strided_iterator(const strided_iterator& other, + BOOST_DEDUCED_TYPENAME enable_if_convertible::type* = 0) : super_t(other) - , m_stride(other.m_stride) - , m_offset(other.m_offset) - , m_max_offset(other.m_max_offset) + , m_last(other.base_end()) + , m_stride(other.get_stride()) { } - strided_iterator& - operator=(const strided_iterator& other) - { - super_t::operator=(other); - m_stride = other.m_stride; - m_offset = other.m_offset; - m_max_offset = other.m_max_offset; - return *this; - } + base_iterator base_end() const { return m_last; } + difference_type get_stride() const { return m_stride; } + private: void increment() { - m_offset += m_stride; - if (m_offset <= m_max_offset) - std::advance(this->base_reference(), m_stride); + base_iterator& it = this->base_reference(); + for (difference_type i = 0; (it != m_last) && (i < m_stride); ++i) + ++it; + } + + base_iterator m_last; + difference_type m_stride; + }; + + // strided_iterator for wrapping a bidirectional iterator + template + class strided_iterator + : public iterator_adaptor< + strided_iterator + , BaseIterator + , use_default + , bidirectional_traversal_tag + > + { + friend class ::boost::iterator_core_access; + + typedef iterator_adaptor< + strided_iterator + , BaseIterator + , use_default + , bidirectional_traversal_tag + > super_t; + public: + typedef BOOST_DEDUCED_TYPENAME std::iterator_traits::difference_type difference_type; + typedef BaseIterator base_iterator; + + strided_iterator() + : m_first() + , m_last() + , m_stride() + { + } + + strided_iterator(base_iterator first, base_iterator it, base_iterator last, difference_type stride) + : super_t(it) + , m_first(first) + , m_last(last) + , m_stride(stride) + { + } + + template + strided_iterator(const strided_iterator& other, + BOOST_DEDUCED_TYPENAME enable_if_convertible::type* = 0) + : super_t(other.base()) + , m_first(other.base_begin()) + , m_last(other.base_end()) + , m_stride(other.get_stride()) + { + } + + base_iterator base_begin() const { return m_first; } + base_iterator base_end() const { return m_last; } + difference_type get_stride() const { return m_stride; } + + private: + void increment() + { + base_iterator& it = this->base_reference(); + for (difference_type i = 0; (it != m_last) && (i < m_stride); ++i) + ++it; } void decrement() { - m_offset -= m_stride; - if (m_offset >= 0) - std::advance(this->base_reference(), -m_stride); + base_iterator& it = this->base_reference(); + for (difference_type i = 0; (it != m_first) && (i < m_stride); ++i) + --it; } - void advance(difference_type n) - { - n *= m_stride; - m_offset += n; + base_iterator m_first; + base_iterator m_last; + difference_type m_stride; + }; - if (m_offset >= 0 && m_offset <= m_max_offset) - std::advance(this->base_reference(), n); + // strided_iterator implementation for wrapping a random access iterator + template + class strided_iterator + : public iterator_adaptor< + strided_iterator + , BaseIterator + , use_default + , random_access_traversal_tag + > + { + friend class ::boost::iterator_core_access; + + typedef iterator_adaptor< + strided_iterator + , BaseIterator + , use_default + , random_access_traversal_tag + > super_t; + public: + typedef BOOST_DEDUCED_TYPENAME super_t::difference_type difference_type; + typedef BaseIterator base_iterator; + + strided_iterator() + : m_first() + , m_last() + , m_stride() + { + } + + strided_iterator(BaseIterator first, BaseIterator it, BaseIterator last, difference_type stride) + : super_t(it) + , m_first(first) + , m_last(last) + , m_stride(stride) + { } template - bool equal(const strided_iterator& other, - BOOST_DEDUCED_TYPENAME enable_if_convertible::type* = 0) const + strided_iterator(const strided_iterator& other, + BOOST_DEDUCED_TYPENAME enable_if_convertible::type* = 0) + : super_t(other.base()) + , m_first(other.base_begin()) + , m_last(other.base_end()) + , m_stride(other.get_stride()) { - return m_offset == other.m_offset; } - difference_type - distance_to(const strided_iterator& other) const + base_iterator base_begin() const { return m_first; } + base_iterator base_end() const { return m_last; } + difference_type get_stride() const { return m_stride; } + + private: + void increment() { - return (other.m_offset - m_offset) / m_stride; + base_iterator& it = this->base_reference(); + if ((m_last - it) > m_stride) + it += m_stride; + else + it = m_last; + } + + void decrement() + { + base_iterator& it = this->base_reference(); + if ((it - m_first) > m_stride) + it -= m_stride; + else + it = m_first; + } + + void advance(difference_type offset) + { + base_iterator& it = this->base_reference(); + offset *= m_stride; + if (offset >= 0) + { + if ((m_last - it) > offset) + it += offset; + else + it = m_last; + } + else + { + if ((m_first - it) > offset) + it += offset; + else + it = m_first; + } + } + + template + difference_type distance_to(const strided_iterator& other, + BOOST_DEDUCED_TYPENAME enable_if_convertible::type* = 0) const + { + if (other.base() >= this->base()) + return (other.base() - this->base() + (m_stride - 1)) / m_stride; + return (other.base() - this->base() - (m_stride - 1)) / m_stride; + } + + bool equal(const strided_iterator& other) const + { + return other.base() == this->base(); } private: + base_iterator m_first; + base_iterator m_last; difference_type m_stride; - difference_type m_offset; - difference_type m_max_offset; }; template inline - strided_iterator - make_strided_iterator( - const BaseIterator& first, - Difference stride, - typename std::iterator_traits::difference_type offset, - typename std::iterator_traits::difference_type max_offset - ) + strided_iterator::type> + make_strided_iterator(BaseIterator first, BaseIterator it, + BaseIterator last, Difference stride) { BOOST_ASSERT( stride >= 0 ); - BOOST_ASSERT( (stride == 0) || (offset % stride == 0) ); - BOOST_ASSERT( (stride == 0) || (max_offset % stride == 0) ); - BOOST_ASSERT( offset <= max_offset ); - return strided_iterator(first, stride, offset, max_offset); + typedef BOOST_DEDUCED_TYPENAME iterator_traversal::type traversal_tag; + return strided_iterator(first, it, last, stride); } - template< class Rng > + template< class Rng + , class Category = BOOST_DEDUCED_TYPENAME iterator_traversal< + BOOST_DEDUCED_TYPENAME range_iterator::type + >::type + > class strided_range - : public iterator_range::type> > + : public iterator_range< + range_detail::strided_iterator< + BOOST_DEDUCED_TYPENAME range_iterator::type, + Category + > + > { - typedef range_detail::strided_iterator::type> iter_type; + typedef range_detail::strided_iterator< + BOOST_DEDUCED_TYPENAME range_iterator::type, + Category + > iter_type; typedef iterator_range super_t; public: template strided_range(Difference stride, Rng& rng) - : super_t(make_super(stride, rng)) + : super_t(make_strided_iterator(boost::begin(rng), boost::begin(rng), boost::end(rng), stride), + make_strided_iterator(boost::begin(rng), boost::end(rng), boost::end(rng), stride)) { BOOST_ASSERT( stride >= 0 ); } - - private: - template - static super_t make_super(const Difference stride, Rng& rng) - { - const Difference count = boost::size(rng); - const Difference max_count = max_offset(count, stride); - return super_t(make_strided_iterator(boost::begin(rng), stride, 0, max_count), - make_strided_iterator(boost::end(rng), stride, max_count, max_count)); - } - - template - static Difference max_offset(Difference sz, const Stride stride) - { - if (stride > 0) - { - sz += stride - 1; - sz /= stride; - sz *= stride; - } - return sz; - } }; template diff --git a/include/boost/range/adaptor/type_erased.hpp b/include/boost/range/adaptor/type_erased.hpp index 85bff73..80bc712 100644 --- a/include/boost/range/adaptor/type_erased.hpp +++ b/include/boost/range/adaptor/type_erased.hpp @@ -1,6 +1,6 @@ // Boost.Range library // -// Copyright Thorsten Ottosen, Neil Groves 2006 - 2008. Use, modification and +// Copyright Neil Groves 2010. Use, modification and // distribution is subject to 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) @@ -10,79 +10,173 @@ #ifndef BOOST_RANGE_ADAPTOR_TYPE_ERASED_HPP_INCLUDED #define BOOST_RANGE_ADAPTOR_TYPE_ERASED_HPP_INCLUDED -#include -#include -#include +#include +#include +#include +#include +#include namespace boost { - namespace range_detail - { - template< - class Value, - class CategoryOrTraversal, - class Reference, - class Difference - > - class any_range - : public iterator_range< - IteratorTypeErasure::any_iterator< - Value, CategoryOrTraversal, Reference, Difference> > - { - typedef typename IteratorTypeErasure::any_iterator< - Value, CategoryOrTraversal, Reference, Difference> iterator_t; - - typedef iterator_range base_t; - public: - template - explicit any_range(Range& r) : base_t(r) {} - - template - explicit any_range(const Range& r) : base_t(r) {} - }; - - template - class any_range_generator - { - public: - typedef any_range< - BOOST_DEDUCED_TYPENAME range_value::type, - BOOST_DEDUCED_TYPENAME iterator_traversal< - BOOST_DEDUCED_TYPENAME range_iterator::type - >::type, - BOOST_DEDUCED_TYPENAME range_reference::type, - BOOST_DEDUCED_TYPENAME range_difference::type - > type; - }; - - class type_erased_tag {}; - - - } // namespace range_detail - - using range_detail::any_range; - namespace adaptors { - namespace + template< + class Value = use_default + , class Traversal = use_default + , class Reference = use_default + , class Difference = use_default + , class Buffer = use_default + > + struct type_erased { - const range_detail::type_erased_tag type_erased = range_detail::type_erased_tag(); + }; + + template< + class SinglePassRange + , class Value + , class Traversal + , class Reference + , class Difference + , class Buffer + > + typename any_range_type_generator< + SinglePassRange + , Value + , Traversal + , Reference + , Difference + , Buffer + >::type + operator|(SinglePassRange& rng, + type_erased< + Value + , Traversal + , Reference + , Difference + , Buffer + >) + { + typedef typename any_range_type_generator< + SinglePassRange + , Value + , Traversal + , Reference + , Difference + , Buffer + >::type range_type; + return range_type(boost::begin(rng), boost::end(rng)); } - template - typename range_detail::any_range_generator::type - operator|(SinglePassRange& rng, range_detail::type_erased_tag) + template< + class SinglePassRange + , class Value + , class Traversal + , class Reference + , class Difference + , class Buffer + > + typename any_range_type_generator< + const SinglePassRange + , Value + , Traversal + , Reference + , Difference + , Buffer + >::type + operator|(const SinglePassRange& rng, + type_erased< + Value + , Traversal + , Reference + , Difference + , Buffer + >) { - typedef typename range_detail::any_range_generator::type range_t; - return range_t(rng); + typedef typename any_range_type_generator< + const SinglePassRange + , Value + , Traversal + , Reference + , Difference + , Buffer + >::type range_type; + return range_type(boost::begin(rng), boost::end(rng)); } - template - typename range_detail::any_range_generator::type - operator|(const SinglePassRange& rng, range_detail::type_erased_tag) + template< + class SinglePassRange + , class Value + , class Traversal + , class Reference + , class Difference + , class Buffer + > + typename any_range_type_generator< + SinglePassRange + , Value + , Traversal + , Reference + , Difference + , Buffer + >::type + type_erase(SinglePassRange& rng + , type_erased< + Value + , Traversal + , Reference + , Difference + , Buffer + > = type_erased<>() + ) { - typedef typename range_detail::any_range_generator::type range_t; - return range_t(rng); + typedef typename any_range_type_generator< + SinglePassRange + , Value + , Traversal + , Reference + , Difference + , Buffer + >::type range_type; + + return range_type(boost::begin(rng), boost::end(rng)); + } + + template< + class SinglePassRange + , class Value + , class Traversal + , class Reference + , class Difference + , class Buffer + > + typename any_range_type_generator< + const SinglePassRange + , Value + , Traversal + , Reference + , Difference + , Buffer + >::type + type_erase(const SinglePassRange& rng + , type_erased< + Value + , Traversal + , Reference + , Difference + , Buffer + > = type_erased<>() + ) + { + typedef typename any_range_type_generator< + const SinglePassRange + , Value + , Traversal + , Reference + , Difference + , Buffer + >::type range_type; + + return range_type(boost::begin(rng), boost::end(rng)); } } } // namespace boost diff --git a/include/boost/range/any_range.hpp b/include/boost/range/any_range.hpp new file mode 100644 index 0000000..2155b2c --- /dev/null +++ b/include/boost/range/any_range.hpp @@ -0,0 +1,204 @@ +// Copyright Neil Groves 2010. Use, modification and +// distribution is subject to 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) +// +// +// For more information, see http://www.boost.org/libs/range/ +// +#ifndef BOOST_RANGE_ANY_RANGE_HPP_INCLUDED +#define BOOST_RANGE_ANY_RANGE_HPP_INCLUDED + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost +{ + namespace range_detail + { + // If T is use_default, return the result of Default, otherwise + // return T. + // + // This is an implementation artifact used to pick intelligent default + // values when the user specified boost::use_default as a template + // parameter. + template< + class T, + class Default + > + struct any_range_default_help + : mpl::eval_if< + is_same + , Default + , mpl::identity + > + { + }; + + template< + class WrappedRange + , class Value + , class Reference + > + struct any_range_value_type + { +# ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY + typedef typename any_range_default_help< + Value + , mpl::eval_if< + is_same + , range_value< + typename remove_const + ::type> + , remove_reference + > + >::type type; +# else + typedef typename any_range_default_help< + Value + , range_value< + typename remove_const + ::type> + >::type type; +# endif + }; + + template< + class Value + , class Traversal + , class Reference + , class Difference + , class Buffer = use_default + > + class any_range + : public iterator_range< + any_iterator< + Value + , Traversal + , Reference + , Difference + , typename any_range_default_help< + Buffer + , mpl::identity + >::type + > + > + { + typedef iterator_range< + any_iterator< + Value + , Traversal + , Reference + , Difference + , typename any_range_default_help< + Buffer + , mpl::identity + >::type + > + > base_type; + + struct enabler {}; + struct disabler {}; + public: + any_range() + { + } + + any_range(const any_range& other) + : base_type(other) + { + } + + template + any_range(WrappedRange& wrapped_range) + : base_type(boost::begin(wrapped_range), + boost::end(wrapped_range)) + { + } + + template + any_range(const WrappedRange& wrapped_range) + : base_type(boost::begin(wrapped_range), + boost::end(wrapped_range)) + { + } + + template< + class OtherValue + , class OtherTraversal + , class OtherReference + , class OtherDifference + > + any_range(const any_range< + OtherValue + , OtherTraversal + , OtherReference + , OtherDifference + , Buffer + >& other) + : base_type(boost::begin(other), boost::end(other)) + { + } + + template + any_range(Iterator first, Iterator last) + : base_type(first, last) + { + } + }; + + template< + class WrappedRange + , class Value = use_default + , class Traversal = use_default + , class Reference = use_default + , class Difference = use_default + , class Buffer = use_default + > + struct any_range_type_generator + { + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept )); + typedef any_range< + typename any_range_value_type< + WrappedRange + , Value + , typename any_range_default_help< + Reference + , range_reference + >::type + >::type + , typename any_range_default_help< + Traversal + , iterator_traversal< + typename range_iterator::type + > + >::type + , typename any_range_default_help< + Reference + , range_reference + >::type + , typename any_range_default_help< + Difference + , range_difference + >::type + , typename any_range_default_help< + Buffer + , mpl::identity + >::type + > type; + }; + } // namespace range_detail + + using range_detail::any_range; + using range_detail::any_range_type_generator; +} // namespace boost + +#endif // include guard diff --git a/include/boost/range/begin.hpp b/include/boost/range/begin.hpp index a4a5e10..c668488 100644 --- a/include/boost/range/begin.hpp +++ b/include/boost/range/begin.hpp @@ -91,6 +91,11 @@ namespace range_detail } // namespace 'range_detail' #endif +// Use a ADL namespace barrier to avoid ambiguity with other unqualified +// calls. This is particularly important with C++0x encouraging +// unqualified calls to begin/end. +namespace range_adl_barrier +{ template< class T > inline BOOST_DEDUCED_TYPENAME range_iterator::type begin( T& r ) @@ -114,19 +119,25 @@ inline BOOST_DEDUCED_TYPENAME range_iterator::type begin( const T& r ) return range_begin( r ); } + } // namespace range_adl_barrier } // namespace boost #endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING namespace boost { - template< class T > - inline BOOST_DEDUCED_TYPENAME range_iterator::type - const_begin( const T& r ) + namespace range_adl_barrier { - return boost::begin( r ); - } -} + template< class T > + inline BOOST_DEDUCED_TYPENAME range_iterator::type + const_begin( const T& r ) + { + return boost::range_adl_barrier::begin( r ); + } + } // namespace range_adl_barrier + + using namespace range_adl_barrier; +} // namespace boost #endif diff --git a/include/boost/range/concepts.hpp b/include/boost/range/concepts.hpp index d9f9bfc..5965293 100644 --- a/include/boost/range/concepts.hpp +++ b/include/boost/range/concepts.hpp @@ -148,13 +148,16 @@ namespace boost { Iterator i2(++i); boost::ignore_unused_variable_warning(i2); - Iterator i3(i++); - boost::ignore_unused_variable_warning(i3); + // deliberately we are loose with the postfix version for the single pass + // iterator due to the commonly poor adherence to the specification means that + // many algorithms would be unusable, whereas actually without the check they + // work + (void)(i++); BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits::reference r1(*i); boost::ignore_unused_variable_warning(r1); - BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits::reference r2(*i++); + BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits::reference r2(*(++i)); boost::ignore_unused_variable_warning(r2); } private: @@ -178,6 +181,20 @@ namespace boost { BOOST_DEDUCED_TYPENAME ForwardIteratorConcept::traversal_category, forward_traversal_tag >)); + + BOOST_CONCEPT_USAGE(ForwardIteratorConcept) + { + // See the above note in the SinglePassIteratorConcept about the handling of the + // postfix increment. Since with forward and better iterators there is no need + // for a proxy, we can sensibly require that the dereference result + // is convertible to reference. + Iterator i2(i++); + boost::ignore_unused_variable_warning(i2); + BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits::reference r(*(i++)); + boost::ignore_unused_variable_warning(r); + } + private: + Iterator i; #endif }; diff --git a/include/boost/range/detail/any_iterator.hpp b/include/boost/range/detail/any_iterator.hpp new file mode 100644 index 0000000..107dfd6 --- /dev/null +++ b/include/boost/range/detail/any_iterator.hpp @@ -0,0 +1,587 @@ +// Boost.Range library +// +// Copyright Neil Groves 2010. Use, modification and +// distribution is subject to 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) +// +// For more information, see http://www.boost.org/libs/range/ +// +#ifndef BOOST_RANGE_DETAIL_ANY_ITERATOR_HPP_INCLUDED +#define BOOST_RANGE_DETAIL_ANY_ITERATOR_HPP_INCLUDED + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost +{ + namespace range_detail + { + // metafunction to determine if T is a const reference + template + struct is_const_reference + { + typedef typename mpl::and_< + typename is_reference::type, + typename is_const< + typename remove_reference::type + >::type + >::type type; + }; + + // metafunction to determine if T is a mutable reference + template + struct is_mutable_reference + { + typedef typename mpl::and_< + typename is_reference::type, + typename mpl::not_< + typename is_const< + typename remove_reference::type + >::type + >::type + >::type type; + }; + + // metafunction to evaluate if a source 'reference' can be + // converted to a target 'reference' as a value. + // + // This is true, when the target reference type is actually + // not a reference, and the source reference is convertible + // to the target type. + template + struct is_convertible_to_value_as_reference + { + typedef typename mpl::and_< + typename mpl::not_< + typename is_reference::type + >::type + , typename is_convertible< + SourceReference + , TargetReference + >::type + >::type type; + }; + + template< + class Value + , class Traversal + , class Reference + , class Difference + , class Buffer = any_iterator_default_buffer + > + class any_iterator; + + // metafunction to determine if SomeIterator is an + // any_iterator. + // + // This is the general implementation which evaluates to false. + template + struct is_any_iterator + : mpl::bool_ + { + }; + + // specialization of is_any_iterator to return true for + // any_iterator classes regardless of template parameters. + template< + class Value + , class Traversal + , class Reference + , class Difference + , class Buffer + > + struct is_any_iterator< + any_iterator< + Value + , Traversal + , Reference + , Difference + , Buffer + > + > + : mpl::bool_ + { + }; + } // namespace range_detail + + namespace detail + { + // Rationale: + // These are specialized since the iterator_facade versions lack + // the requisite typedefs to allow wrapping to determine the types + // if a user copy constructs from a postfix increment. + + template< + class Value + , class Traversal + , class Reference + , class Difference + , class Buffer + > + class postfix_increment_proxy< + range_detail::any_iterator< + Value + , Traversal + , Reference + , Difference + , Buffer + > + > + { + typedef range_detail::any_iterator< + Value + , Traversal + , Reference + , Difference + , Buffer + > any_iterator_type; + + public: + typedef Value value_type; + typedef typename std::iterator_traits::iterator_category iterator_category; + typedef Difference difference_type; + typedef typename iterator_pointer::type pointer; + typedef Reference reference; + + explicit postfix_increment_proxy(any_iterator_type const& x) + : stored_value(*x) + {} + + value_type& + operator*() const + { + return this->stored_value; + } + private: + mutable value_type stored_value; + }; + + template< + class Value + , class Traversal + , class Reference + , class Difference + , class Buffer + > + class writable_postfix_increment_proxy< + range_detail::any_iterator< + Value + , Traversal + , Reference + , Difference + , Buffer + > + > + { + typedef range_detail::any_iterator< + Value + , Traversal + , Reference + , Difference + , Buffer + > any_iterator_type; + public: + typedef Value value_type; + typedef typename std::iterator_traits::iterator_category iterator_category; + typedef Difference difference_type; + typedef typename iterator_pointer::type pointer; + typedef Reference reference; + + explicit writable_postfix_increment_proxy(any_iterator_type const& x) + : stored_value(*x) + , stored_iterator(x) + {} + + // Dereferencing must return a proxy so that both *r++ = o and + // value_type(*r++) can work. In this case, *r is the same as + // *r++, and the conversion operator below is used to ensure + // readability. + writable_postfix_increment_proxy const& + operator*() const + { + return *this; + } + + // Provides readability of *r++ + operator value_type&() const + { + return stored_value; + } + + // Provides writability of *r++ + template + T const& operator=(T const& x) const + { + *this->stored_iterator = x; + return x; + } + + // This overload just in case only non-const objects are writable + template + T& operator=(T& x) const + { + *this->stored_iterator = x; + return x; + } + + // Provides X(r++) + operator any_iterator_type const&() const + { + return stored_iterator; + } + + private: + mutable value_type stored_value; + any_iterator_type stored_iterator; + }; + + + } + + namespace range_detail + { + template< + class Value + , class Traversal + , class Reference + , class Difference + , class Buffer + > + class any_iterator + : public iterator_facade< + any_iterator< + Value + , Traversal + , Reference + , Difference + , Buffer + > + , Value + , Traversal + , Reference + , Difference + > + { + template< + class OtherValue + , class OtherTraversal + , class OtherReference + , class OtherDifference + , class OtherBuffer + > + friend class any_iterator; + + struct enabler {}; + struct disabler {}; + + typedef typename any_iterator_interface_type_generator< + Traversal + , Reference + , Difference + , Buffer + >::type abstract_base_type; + + typedef iterator_facade< + any_iterator< + Value + , Traversal + , Reference + , Difference + , Buffer + > + , Value + , Traversal + , Reference + , Difference + > base_type; + + typedef Buffer buffer_type; + + public: + typedef typename base_type::value_type value_type; + typedef typename base_type::reference reference; + typedef typename base_type::difference_type difference_type; + + // Default constructor + any_iterator() + : m_impl(0) {} + + // Simple copy construction without conversion + any_iterator(const any_iterator& other) + : base_type(other) + , m_impl(other.m_impl + ? other.m_impl->clone(m_buffer) + : 0) + { + } + + // Simple assignment operator without conversion + any_iterator& operator=(const any_iterator& other) + { + if (this != &other) + { + if (m_impl) + m_impl->~abstract_base_type(); + m_buffer.deallocate(); + m_impl = 0; + if (other.m_impl) + m_impl = other.m_impl->clone(m_buffer); + } + return *this; + } + + // Implicit conversion from another any_iterator where the + // conversion is from a non-const reference to a const reference + template< + class OtherValue + , class OtherTraversal + , class OtherReference + , class OtherDifference + > + any_iterator(const any_iterator< + OtherValue, + OtherTraversal, + OtherReference, + OtherDifference, + Buffer + >& other, + typename enable_if< + typename mpl::and_< + typename is_mutable_reference::type, + typename is_const_reference::type + >::type, + enabler + >::type* = 0 + ) + : m_impl(other.m_impl + ? other.m_impl->clone_const_ref(m_buffer) + : 0 + ) + { + } + + // Implicit conversion from another any_iterator where the + // reference types of the source and the target are references + // that are either both const, or both non-const. + template< + class OtherValue + , class OtherTraversal + , class OtherReference + , class OtherDifference + > + any_iterator(const any_iterator< + OtherValue + , OtherTraversal + , OtherReference + , OtherDifference + , Buffer + >& other, + typename enable_if< + typename mpl::or_< + typename mpl::and_< + typename is_mutable_reference::type, + typename is_mutable_reference::type + >::type, + typename mpl::and_< + typename is_const_reference::type, + typename is_const_reference::type + >::type + >::type, + enabler + >::type* = 0 + ) + : m_impl(other.m_impl + ? other.m_impl->clone(m_buffer) + : 0 + ) + { + } + + // Implicit conversion to an any_iterator that uses a value for + // the reference type. + template< + class OtherValue + , class OtherTraversal + , class OtherReference + , class OtherDifference + > + any_iterator(const any_iterator< + OtherValue + , OtherTraversal + , OtherReference + , OtherDifference + , Buffer + >& other, + typename enable_if< + typename is_convertible_to_value_as_reference< + OtherReference + , Reference + >::type, + enabler + >::type* = 0 + ) + : m_impl(other.m_impl + ? other.m_impl->clone_reference_as_value(m_buffer) + : 0 + ) + { + } + + any_iterator clone() const + { + any_iterator result; + if (m_impl) + result.m_impl = m_impl->clone(result.m_buffer); + return result; + } + + any_iterator< + Value + , Traversal + , typename abstract_base_type::const_reference + , Difference + , Buffer + > + clone_const_ref() const + { + typedef any_iterator< + Value + , Traversal + , typename abstract_base_type::const_reference + , Difference + , Buffer + > result_type; + + result_type result; + + if (m_impl) + result.m_impl = m_impl->clone_const_ref(result.m_buffer); + + return result; + } + + // implicit conversion and construction from type-erasure-compatible + // iterators + template + explicit any_iterator( + const WrappedIterator& wrapped_iterator, + typename disable_if< + typename is_any_iterator::type + , disabler + >::type* = 0 + ) + { + typedef typename any_iterator_wrapper_type_generator< + WrappedIterator + , Traversal + , Reference + , Difference + , Buffer + >::type wrapper_type; + + void* ptr = m_buffer.allocate(sizeof(wrapper_type)); + m_impl = new(ptr) wrapper_type(wrapped_iterator); + } + + ~any_iterator() + { + // manually run the destructor, the deallocation is automatically + // handled by the any_iterator_small_buffer base class. + if (m_impl) + m_impl->~abstract_base_type(); + } + + private: + friend class ::boost::iterator_core_access; + + Reference dereference() const + { + BOOST_ASSERT( m_impl ); + return m_impl->dereference(); + } + + bool equal(const any_iterator& other) const + { + return (m_impl == other.m_impl) + || (m_impl && other.m_impl && m_impl->equal(*other.m_impl)); + } + + void increment() + { + BOOST_ASSERT( m_impl ); + m_impl->increment(); + } + + void decrement() + { + BOOST_ASSERT( m_impl ); + m_impl->decrement(); + } + + Difference distance_to(const any_iterator& other) const + { + return m_impl && other.m_impl + ? m_impl->distance_to(*other.m_impl) + : 0; + } + + void advance(Difference offset) + { + BOOST_ASSERT( m_impl ); + m_impl->advance(offset); + } + + any_iterator& swap(any_iterator& other) + { + BOOST_ASSERT( this != &other ); + // grab a temporary copy of the other iterator + any_iterator tmp(other); + + // deallocate the other iterator, taking care to obey the + // class-invariants in-case of exceptions later + if (other.m_impl) + { + other.m_impl->~abstract_base_type(); + other.m_buffer.deallocate(); + other.m_impl = 0; + } + + // If this is a non-null iterator then we need to put + // a clone of this iterators impementation into the other + // iterator. + // We can't just swap because of the small buffer optimization. + if (m_impl) + { + other.m_impl = m_impl->clone(other.m_buffer); + m_impl->~abstract_base_type(); + m_buffer.deallocate(); + m_impl = 0; + } + + // assign to this instance a clone of the temporarily held + // tmp which represents the input other parameter at the + // start of execution of this function. + if (tmp.m_impl) + m_impl = tmp.m_impl->clone(m_buffer); + + return *this; + } + + buffer_type m_buffer; + abstract_base_type* m_impl; + }; + + } // namespace range_detail +} // namespace boost + +#endif // include guard diff --git a/include/boost/range/detail/any_iterator_buffer.hpp b/include/boost/range/detail/any_iterator_buffer.hpp new file mode 100644 index 0000000..26c1420 --- /dev/null +++ b/include/boost/range/detail/any_iterator_buffer.hpp @@ -0,0 +1,117 @@ +// Boost.Range library +// +// Copyright Neil Groves 2010. Use, modification and +// distribution is subject to 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) +// +// For more information, see http://www.boost.org/libs/range/ +// +#ifndef BOOST_RANGE_DETAIL_ANY_ITERATOR_BUFFER_HPP_INCLUDED +#define BOOST_RANGE_DETAIL_ANY_ITERATOR_BUFFER_HPP_INCLUDED + +#include +#include +#include +#include + +namespace boost +{ + template + class any_iterator_buffer + : noncopyable + { + BOOST_STATIC_ASSERT(( StackBufferSize > 0 )); + public: + any_iterator_buffer() + : m_ptr() + { + } + + ~any_iterator_buffer() + { + delete [] m_ptr; + } + + void* allocate(std::size_t bytes) + { + BOOST_ASSERT( !m_ptr ); + if (bytes <= StackBufferSize) + return m_buffer.data(); + + m_ptr = new char[bytes]; + return m_ptr; + } + + void deallocate() + { + delete [] m_ptr; + m_ptr = 0; + } + + private: + // Rationale: + // Do not use inheritance from noncopyable because this causes + // the concepts to erroneous detect the derived any_iterator + // as noncopyable. + any_iterator_buffer(const any_iterator_buffer&); + void operator=(const any_iterator_buffer&); + + char* m_ptr; + boost::array m_buffer; + }; + + class any_iterator_heap_only_buffer + : noncopyable + { + public: + any_iterator_heap_only_buffer() + : m_ptr() + { + } + + ~any_iterator_heap_only_buffer() + { + delete [] m_ptr; + } + + void* allocate(std::size_t bytes) + { + BOOST_ASSERT( !m_ptr ); + m_ptr = new char[bytes]; + return m_ptr; + } + + void deallocate() + { + delete [] m_ptr; + m_ptr = 0; + } + + private: + char* m_ptr; + }; + + template + class any_iterator_stack_only_buffer + { + BOOST_STATIC_ASSERT(( StackBufferSize > 0 )); + public: + void* allocate(std::size_t bytes) + { + BOOST_ASSERT( bytes <= m_buffer.size() ); + return m_buffer.data(); + } + + void deallocate() + { + } + + private: + boost::array m_buffer; + }; + + typedef any_iterator_buffer<64> any_iterator_default_buffer; +} // namespace boost + +#endif // include guard diff --git a/include/boost/range/detail/any_iterator_interface.hpp b/include/boost/range/detail/any_iterator_interface.hpp new file mode 100644 index 0000000..d8f4de7 --- /dev/null +++ b/include/boost/range/detail/any_iterator_interface.hpp @@ -0,0 +1,258 @@ +// Boost.Range library +// +// Copyright Neil Groves 2010. Use, modification and +// distribution is subject to 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) +// +// For more information, see http://www.boost.org/libs/range/ +// +#ifndef BOOST_RANGE_DETAIL_ANY_ITERATOR_INTERFACE_HPP_INCLUDED +#define BOOST_RANGE_DETAIL_ANY_ITERATOR_INTERFACE_HPP_INCLUDED + +#include +#include +#include + +namespace boost +{ + namespace range_detail + { + template + struct const_reference_type_generator + { + typedef typename mpl::if_< + typename is_reference::type, + typename add_reference< + typename add_const< + typename remove_reference::type + >::type + >::type, + T + >::type type; + }; + + template< + class Reference + , class Buffer + > + struct any_incrementable_iterator_interface + { + typedef Reference reference; + typedef typename const_reference_type_generator< + Reference + >::type const_reference; + typedef typename remove_const< + typename remove_reference::type + >::type reference_as_value_type; + + typedef Buffer buffer_type; + + virtual ~any_incrementable_iterator_interface() {} + + virtual any_incrementable_iterator_interface* + clone(buffer_type& buffer) const = 0; + + virtual any_incrementable_iterator_interface* + clone_const_ref(buffer_type& buffer) const = 0; + + virtual any_incrementable_iterator_interface* + clone_reference_as_value(buffer_type& buffer) const = 0; + + virtual void increment() = 0; + }; + + template< + class Reference + , class Buffer + > + struct any_single_pass_iterator_interface + : any_incrementable_iterator_interface + { + typedef typename any_incrementable_iterator_interface::reference reference; + typedef typename any_incrementable_iterator_interface::const_reference const_reference; + typedef typename any_incrementable_iterator_interface::buffer_type buffer_type; + typedef typename any_incrementable_iterator_interface::reference_as_value_type reference_as_value_type; + + virtual any_single_pass_iterator_interface* + clone(buffer_type& buffer) const = 0; + + virtual any_single_pass_iterator_interface* + clone_const_ref(buffer_type& buffer) const = 0; + + virtual any_single_pass_iterator_interface* + clone_reference_as_value(buffer_type& buffer) const = 0; + + virtual Reference dereference() const = 0; + + virtual bool equal(const any_single_pass_iterator_interface& other) const = 0; + }; + + template< + class Reference + , class Buffer + > + struct any_forward_iterator_interface + : any_single_pass_iterator_interface + { + typedef typename any_single_pass_iterator_interface::reference reference; + typedef typename any_single_pass_iterator_interface::const_reference const_reference; + typedef typename any_single_pass_iterator_interface::buffer_type buffer_type; + typedef typename any_single_pass_iterator_interface::reference_as_value_type reference_as_value_type; + + virtual any_forward_iterator_interface* + clone(buffer_type& buffer) const = 0; + + virtual any_forward_iterator_interface* + clone_const_ref(buffer_type& buffer) const = 0; + + virtual any_forward_iterator_interface* + clone_reference_as_value(buffer_type& buffer) const = 0; + }; + + template< + class Reference + , class Buffer + > + struct any_bidirectional_iterator_interface + : any_forward_iterator_interface + { + typedef typename any_forward_iterator_interface::reference reference; + typedef typename any_forward_iterator_interface::const_reference const_reference; + typedef typename any_forward_iterator_interface::buffer_type buffer_type; + typedef typename any_forward_iterator_interface::reference_as_value_type reference_as_value_type; + + virtual any_bidirectional_iterator_interface* + clone(buffer_type& buffer) const = 0; + + virtual any_bidirectional_iterator_interface* + clone_const_ref(buffer_type& buffer) const = 0; + + virtual any_bidirectional_iterator_interface* + clone_reference_as_value(buffer_type& buffer) const = 0; + + virtual void decrement() = 0; + }; + + template< + class Reference + , class Difference + , class Buffer + > + struct any_random_access_iterator_interface + : any_bidirectional_iterator_interface< + Reference + , Buffer + > + { + typedef typename any_bidirectional_iterator_interface::reference reference; + typedef typename any_bidirectional_iterator_interface::const_reference const_reference; + typedef typename any_bidirectional_iterator_interface::buffer_type buffer_type; + typedef typename any_bidirectional_iterator_interface::reference_as_value_type reference_as_value_type; + typedef Difference difference_type; + + virtual any_random_access_iterator_interface* + clone(buffer_type& buffer) const = 0; + + virtual any_random_access_iterator_interface* + clone_const_ref(buffer_type& buffer) const = 0; + + virtual any_random_access_iterator_interface* + clone_reference_as_value(buffer_type& buffer) const = 0; + + virtual void advance(Difference offset) = 0; + + virtual Difference distance_to(const any_random_access_iterator_interface& other) const = 0; + }; + + template< + class Traversal + , class Reference + , class Difference + , class Buffer + > + struct any_iterator_interface_type_generator; + + template< + class Reference + , class Difference + , class Buffer + > + struct any_iterator_interface_type_generator< + incrementable_traversal_tag + , Reference + , Difference + , Buffer + > + { + typedef any_incrementable_iterator_interface type; + }; + + template< + class Reference + , class Difference + , class Buffer + > + struct any_iterator_interface_type_generator< + single_pass_traversal_tag + , Reference + , Difference + , Buffer + > + { + typedef any_single_pass_iterator_interface type; + }; + + template< + class Reference + , class Difference + , class Buffer + > + struct any_iterator_interface_type_generator< + forward_traversal_tag + , Reference + , Difference + , Buffer + > + { + typedef any_forward_iterator_interface type; + }; + + template< + class Reference + , class Difference + , class Buffer + > + struct any_iterator_interface_type_generator< + bidirectional_traversal_tag + , Reference + , Difference + , Buffer + > + { + typedef any_bidirectional_iterator_interface type; + }; + + template< + class Reference + , class Difference + , class Buffer + > + struct any_iterator_interface_type_generator< + random_access_traversal_tag + , Reference + , Difference + , Buffer + > + { + typedef any_random_access_iterator_interface< + Reference + , Difference + , Buffer + > type; + }; + + } // namespace range_detail +} // namespace boost + +#endif // include guard diff --git a/include/boost/range/detail/any_iterator_wrapper.hpp b/include/boost/range/detail/any_iterator_wrapper.hpp new file mode 100644 index 0000000..b5313a7 --- /dev/null +++ b/include/boost/range/detail/any_iterator_wrapper.hpp @@ -0,0 +1,590 @@ +// Boost.Range library +// +// Copyright Neil Groves 2010. Use, modification and +// distribution is subject to 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) +// +// For more information, see http://www.boost.org/libs/range/ +// +#ifndef BOOST_RANGE_DETAIL_ANY_ITERATOR_WRAPPER_HPP_INCLUDED +#define BOOST_RANGE_DETAIL_ANY_ITERATOR_WRAPPER_HPP_INCLUDED + +#include +#include + +namespace boost +{ + namespace range_detail + { + template< + class WrappedIterator + , class Reference + , class Buffer + > + class any_incrementable_iterator_wrapper + : public any_incrementable_iterator_interface< + Reference + , Buffer + > + { + BOOST_RANGE_CONCEPT_ASSERT(( IncrementableIteratorConcept )); + public: + typedef WrappedIterator wrapped_type; + + BOOST_STATIC_ASSERT(( is_convertible< + typename iterator_reference::type + , Reference + >::value )); + + any_incrementable_iterator_wrapper() + : m_it() + {} + + explicit any_incrementable_iterator_wrapper(wrapped_type it) + : m_it(it) + {} + + // any_incrementable_iterator implementation + virtual any_incrementable_iterator_wrapper* clone( + typename any_incrementable_iterator_wrapper::buffer_type& buffer + ) const + { + return new (buffer.allocate(sizeof(*this))) + any_incrementable_iterator_wrapper(m_it); + } + + virtual any_incrementable_iterator_wrapper< + WrappedIterator + , typename any_incrementable_iterator_wrapper::const_reference + , Buffer + >* clone_const_ref( + typename any_incrementable_iterator_wrapper::buffer_type& buffer + ) const + { + typedef any_incrementable_iterator_wrapper< + WrappedIterator + , typename any_incrementable_iterator_wrapper::const_reference + , Buffer + > result_type; + + return new (buffer.allocate(sizeof(result_type))) + result_type(m_it); + } + + virtual any_incrementable_iterator_wrapper< + WrappedIterator + , typename any_incrementable_iterator_wrapper::reference_as_value_type + , Buffer + >* clone_reference_as_value( + typename any_incrementable_iterator_wrapper::buffer_type& buffer + ) const + { + typedef any_incrementable_iterator_wrapper< + WrappedIterator + , typename any_incrementable_iterator_wrapper::reference_as_value_type + , Buffer + > result_type; + + return new (buffer.allocate(sizeof(result_type))) + result_type(m_it); + } + + virtual void increment() + { + ++m_it; + } + + private: + wrapped_type m_it; + }; + + template< + class WrappedIterator + , class Reference + , class Buffer + > + class any_single_pass_iterator_wrapper + : public any_single_pass_iterator_interface< + Reference + , Buffer + > + { + struct disabler {}; + BOOST_RANGE_CONCEPT_ASSERT(( SinglePassIteratorConcept )); + public: + + any_single_pass_iterator_wrapper() + : m_it() + {} + + explicit any_single_pass_iterator_wrapper(const WrappedIterator& it) + : m_it(it) + {} + // any_single_pass_iterator_interface implementation + virtual any_single_pass_iterator_wrapper* clone( + typename any_single_pass_iterator_wrapper::buffer_type& buffer + ) const + { + return new (buffer.allocate(sizeof(*this))) + any_single_pass_iterator_wrapper(m_it); + } + + virtual any_single_pass_iterator_wrapper< + WrappedIterator + , typename any_single_pass_iterator_wrapper::const_reference + , Buffer + >* clone_const_ref( + typename any_single_pass_iterator_wrapper::buffer_type& buffer + ) const + { + typedef any_single_pass_iterator_wrapper< + WrappedIterator + , typename any_single_pass_iterator_wrapper::const_reference + , Buffer + > result_type; + + return new (buffer.allocate(sizeof(result_type))) + result_type(m_it); + } + + virtual any_single_pass_iterator_wrapper< + WrappedIterator + , typename any_single_pass_iterator_wrapper::reference_as_value_type + , Buffer + >* clone_reference_as_value( + typename any_single_pass_iterator_wrapper::buffer_type& buffer + ) const + { + typedef any_single_pass_iterator_wrapper< + WrappedIterator + , typename any_single_pass_iterator_wrapper::reference_as_value_type + , Buffer + > result_type; + + return new (buffer.allocate(sizeof(result_type))) + result_type(m_it); + } + + virtual void increment() + { + ++m_it; + } + + virtual bool equal(const any_single_pass_iterator_interface& other) const + { + return m_it == boost::polymorphic_downcast(&other)->m_it; + } + + virtual Reference dereference() const + { + return *m_it; + } + + private: + WrappedIterator m_it; + }; + + template< + class WrappedIterator + , class Reference + , class Buffer + > + class any_forward_iterator_wrapper + : public any_forward_iterator_interface< + Reference + , Buffer + > + { + BOOST_RANGE_CONCEPT_ASSERT(( ForwardIteratorConcept )); + public: + any_forward_iterator_wrapper() + : m_it() + {} + + explicit any_forward_iterator_wrapper(const WrappedIterator& it) + : m_it(it) + {} + + // any_forward_iterator_interface implementation + virtual any_forward_iterator_wrapper* clone( + typename any_forward_iterator_wrapper::buffer_type& buffer + ) const + { + return new (buffer.allocate(sizeof(*this))) + any_forward_iterator_wrapper(m_it); + } + + virtual any_forward_iterator_wrapper< + WrappedIterator + , typename any_forward_iterator_wrapper::const_reference + , Buffer + >* clone_const_ref( + typename any_forward_iterator_wrapper::buffer_type& buffer + ) const + { + typedef any_forward_iterator_wrapper< + WrappedIterator + , typename any_forward_iterator_wrapper::const_reference + , Buffer + > result_type; + + return new (buffer.allocate(sizeof(result_type))) + result_type(m_it); + } + + virtual any_forward_iterator_wrapper< + WrappedIterator + , typename any_forward_iterator_wrapper::reference_as_value_type + , Buffer + >* clone_reference_as_value( + typename any_forward_iterator_wrapper::buffer_type& buffer + ) const + { + typedef any_forward_iterator_wrapper< + WrappedIterator + , typename any_forward_iterator_wrapper::reference_as_value_type + , Buffer + > result_type; + + return new (buffer.allocate(sizeof(result_type))) + result_type(m_it); + } + + virtual void increment() + { + ++m_it; + } + + virtual bool equal(const any_single_pass_iterator_interface& other) const + { + return m_it == boost::polymorphic_downcast(&other)->m_it; + } + + virtual Reference dereference() const + { + return *m_it; + } + private: + WrappedIterator m_it; + }; + + template< + class WrappedIterator + , class Reference + , class Buffer + > + class any_bidirectional_iterator_wrapper + : public any_bidirectional_iterator_interface< + Reference + , Buffer + > + { + BOOST_RANGE_CONCEPT_ASSERT(( BidirectionalIteratorConcept )); + public: + any_bidirectional_iterator_wrapper() + : m_it() + { + } + + explicit any_bidirectional_iterator_wrapper(const WrappedIterator& it) + : m_it(it) + { + } + + virtual any_bidirectional_iterator_wrapper* clone( + typename any_bidirectional_iterator_wrapper::buffer_type& buffer + ) const + { + return new (buffer.allocate(sizeof(*this))) + any_bidirectional_iterator_wrapper(*this); + } + + virtual any_bidirectional_iterator_wrapper< + WrappedIterator + , typename any_bidirectional_iterator_wrapper::const_reference + , Buffer + >* clone_const_ref( + typename any_bidirectional_iterator_wrapper::buffer_type& buffer + ) const + { + typedef any_bidirectional_iterator_wrapper< + WrappedIterator + , typename any_bidirectional_iterator_wrapper::const_reference + , Buffer + > result_type; + + return new (buffer.allocate(sizeof(result_type))) + result_type(m_it); + } + + virtual any_bidirectional_iterator_wrapper< + WrappedIterator + , typename any_bidirectional_iterator_wrapper::reference_as_value_type + , Buffer + >* clone_reference_as_value( + typename any_bidirectional_iterator_wrapper::buffer_type& buffer + ) const + { + typedef any_bidirectional_iterator_wrapper< + WrappedIterator + , typename any_bidirectional_iterator_wrapper::reference_as_value_type + , Buffer + > result_type; + + return new (buffer.allocate(sizeof(result_type))) + result_type(m_it); + } + + virtual void increment() + { + ++m_it; + } + + virtual void decrement() + { + --m_it; + } + + virtual bool equal(const any_single_pass_iterator_interface& other) const + { + return m_it == boost::polymorphic_downcast(&other)->m_it; + } + + virtual Reference dereference() const + { + return *m_it; + } + + private: + WrappedIterator m_it; + }; + + template< + class WrappedIterator + , class Reference + , class Difference + , class Buffer + > + class any_random_access_iterator_wrapper + : public any_random_access_iterator_interface< + Reference + , Difference + , Buffer + > + { + BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessIteratorConcept )); + public: + typedef Difference difference_type; + + any_random_access_iterator_wrapper() + : m_it() + { + } + + explicit any_random_access_iterator_wrapper(const WrappedIterator& other) + : m_it(other) + { + } + + virtual any_random_access_iterator_wrapper* clone( + typename any_random_access_iterator_wrapper::buffer_type& buffer + ) const + { + return new (buffer.allocate(sizeof(*this))) + any_random_access_iterator_wrapper(*this); + } + + virtual any_random_access_iterator_wrapper< + WrappedIterator + , typename any_random_access_iterator_wrapper::const_reference + , Difference + , Buffer + >* clone_const_ref( + typename any_random_access_iterator_wrapper::buffer_type& buffer + ) const + { + typedef any_random_access_iterator_wrapper< + WrappedIterator + , typename any_random_access_iterator_wrapper::const_reference + , Difference + , Buffer + > result_type; + + return new (buffer.allocate(sizeof(result_type))) + result_type(m_it); + } + + virtual any_random_access_iterator_wrapper< + WrappedIterator + , typename any_random_access_iterator_wrapper::reference_as_value_type + , Difference + , Buffer + >* clone_reference_as_value( + typename any_random_access_iterator_wrapper::buffer_type& buffer + ) const + { + typedef any_random_access_iterator_wrapper< + WrappedIterator + , typename any_random_access_iterator_wrapper::reference_as_value_type + , Difference + , Buffer + > result_type; + + return new (buffer.allocate(sizeof(result_type))) + result_type(m_it); + } + + virtual void increment() + { + ++m_it; + } + + virtual bool equal(const any_single_pass_iterator_interface& other) const + { + return m_it == boost::polymorphic_downcast(&other)->m_it; + } + + virtual void decrement() + { + --m_it; + } + + virtual void advance(Difference offset) + { + m_it += offset; + } + + virtual Reference dereference() const + { + return *m_it; + } + + virtual Difference distance_to(const any_random_access_iterator_interface& other) const + { + return boost::polymorphic_downcast(&other)->m_it - m_it; + } + + private: + WrappedIterator m_it; + }; + + template< + class WrappedIterator + , class Traversal + , class Reference + , class Difference + , class Buffer + > + struct any_iterator_wrapper_type_generator; + + template< + class WrappedIterator + , class Reference + , class Difference + , class Buffer + > + struct any_iterator_wrapper_type_generator< + WrappedIterator + , incrementable_traversal_tag + , Reference + , Difference + , Buffer + > + { + typedef any_incrementable_iterator_wrapper< + WrappedIterator + , Reference + , Buffer + > type; + }; + + template< + class WrappedIterator + , class Reference + , class Difference + , class Buffer + > + struct any_iterator_wrapper_type_generator< + WrappedIterator + , single_pass_traversal_tag + , Reference + , Difference + , Buffer + > + { + typedef any_single_pass_iterator_wrapper< + WrappedIterator + , Reference + , Buffer + > type; + }; + + template< + class WrappedIterator + , class Reference + , class Difference + , class Buffer + > + struct any_iterator_wrapper_type_generator< + WrappedIterator + , forward_traversal_tag + , Reference + , Difference + , Buffer + > + { + typedef any_forward_iterator_wrapper< + WrappedIterator + , Reference + , Buffer + > type; + }; + + template< + class WrappedIterator + , class Reference + , class Difference + , class Buffer + > + struct any_iterator_wrapper_type_generator< + WrappedIterator + , bidirectional_traversal_tag + , Reference + , Difference + , Buffer + > + { + typedef any_bidirectional_iterator_wrapper< + WrappedIterator + , Reference + , Buffer + > type; + }; + + template< + class WrappedIterator + , class Reference + , class Difference + , class Buffer + > + struct any_iterator_wrapper_type_generator< + WrappedIterator + , random_access_traversal_tag + , Reference + , Difference + , Buffer + > + { + typedef any_random_access_iterator_wrapper< + WrappedIterator + , Reference + , Difference + , Buffer + > type; + }; + + } // namespace range_detail +} // namespace boost + +#endif // include guard diff --git a/include/boost/range/detail/begin.hpp b/include/boost/range/detail/begin.hpp old mode 100755 new mode 100644 index 06c2561..f3da732 --- a/include/boost/range/detail/begin.hpp +++ b/include/boost/range/detail/begin.hpp @@ -19,9 +19,9 @@ # include #endif -namespace boost +namespace boost { - + namespace range_detail { template< typename T > @@ -30,7 +30,7 @@ namespace boost ////////////////////////////////////////////////////////////////////// // default ////////////////////////////////////////////////////////////////////// - + template<> struct range_begin { @@ -40,11 +40,11 @@ namespace boost return c.begin(); }; }; - + ////////////////////////////////////////////////////////////////////// // pair ////////////////////////////////////////////////////////////////////// - + template<> struct range_begin { @@ -54,11 +54,11 @@ namespace boost return p.first; } }; - + ////////////////////////////////////////////////////////////////////// // array ////////////////////////////////////////////////////////////////////// - + template<> struct range_begin { @@ -78,14 +78,16 @@ namespace boost }; } // namespace 'range_detail' - - template< typename C > - inline BOOST_RANGE_DEDUCED_TYPENAME range_iterator::type - begin( C& c ) + + namespace range_adl_barrier { - return range_detail::range_begin< BOOST_RANGE_DEDUCED_TYPENAME range_detail::range::type >::fun( c ); + template< typename C > + inline BOOST_RANGE_DEDUCED_TYPENAME range_iterator::type + begin( C& c ) + { + return range_detail::range_begin< BOOST_RANGE_DEDUCED_TYPENAME range_detail::range::type >::fun( c ); + } } - } // namespace 'boost' diff --git a/include/boost/range/detail/end.hpp b/include/boost/range/detail/end.hpp old mode 100755 new mode 100644 index d6a7368..8b5f35d --- a/include/boost/range/detail/end.hpp +++ b/include/boost/range/detail/end.hpp @@ -24,7 +24,7 @@ # include # endif -namespace boost +namespace boost { namespace range_detail { @@ -34,39 +34,39 @@ namespace boost ////////////////////////////////////////////////////////////////////// // default ////////////////////////////////////////////////////////////////////// - + template<> struct range_end { template< typename C > - static BOOST_RANGE_DEDUCED_TYPENAME range_iterator::type + static BOOST_RANGE_DEDUCED_TYPENAME range_iterator::type fun( C& c ) { return c.end(); }; }; - + ////////////////////////////////////////////////////////////////////// // pair ////////////////////////////////////////////////////////////////////// - + template<> struct range_end { template< typename P > - static BOOST_RANGE_DEDUCED_TYPENAME range_iterator

::type + static BOOST_RANGE_DEDUCED_TYPENAME range_iterator

::type fun( const P& p ) { return p.second; } }; - + ////////////////////////////////////////////////////////////////////// // array ////////////////////////////////////////////////////////////////////// - + template<> - struct range_end + struct range_end { #if !BOOST_WORKAROUND(BOOST_MSVC, < 1310) template< typename T, std::size_t sz > @@ -82,16 +82,19 @@ namespace boost } #endif }; - + } // namespace 'range_detail' - - template< typename C > - inline BOOST_RANGE_DEDUCED_TYPENAME range_iterator::type - end( C& c ) + + namespace range_adl_barrier { - return range_detail::range_end< BOOST_RANGE_DEDUCED_TYPENAME range_detail::range::type >::fun( c ); - } - + template< typename C > + inline BOOST_RANGE_DEDUCED_TYPENAME range_iterator::type + end( C& c ) + { + return range_detail::range_end< BOOST_RANGE_DEDUCED_TYPENAME range_detail::range::type >::fun( c ); + } + } // namespace range_adl_barrier + } // namespace 'boost' # endif // VC6 diff --git a/include/boost/range/detail/safe_bool.hpp b/include/boost/range/detail/safe_bool.hpp new file mode 100644 index 0000000..182e510 --- /dev/null +++ b/include/boost/range/detail/safe_bool.hpp @@ -0,0 +1,72 @@ +// This header intentionally has no include guards. +// +// Copyright (c) 2010 Neil Groves +// 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 +// +// This code utilises the experience gained during the evolution of +// +#ifndef BOOST_RANGE_SAFE_BOOL_INCLUDED_HPP +#define BOOST_RANGE_SAFE_BOOL_INCLUDED_HPP + +#include +#include + +namespace boost +{ + namespace range_detail + { + +template +class safe_bool +{ +public: + typedef safe_bool this_type; + +#if (defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, < 0x570)) || defined(__CINT_) + typedef bool unspecified_bool_type; + static unspecified_bool_type to_unspecified_bool(const bool x, DataMemberPtr) + { + return x; + } +#elif defined(_MANAGED) + static void unspecified_bool(this_type***) + { + } + typedef void(*unspecified_bool_type)(this_type***); + static unspecified_bool_type to_unspecified_bool(const bool x, DataMemberPtr) + { + return x ? unspecified_bool : 0; + } +#elif \ + ( defined(__MWERKS__) && BOOST_WORKAROUND(__MWERKS__, < 0x3200) ) || \ + ( defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ < 304) ) || \ + ( defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x590) ) + + typedef bool (this_type::*unspecified_bool_type)() const; + + static unspecified_bool_type to_unspecified_bool(const bool x, DataMemberPtr) + { + return x ? &this_type::detail_safe_bool_member_fn : 0; + } +private: + bool detail_safe_bool_member_fn() const { return false; } +#else + typedef DataMemberPtr unspecified_bool_type; + static unspecified_bool_type to_unspecified_bool(const bool x, DataMemberPtr p) + { + return x ? p : 0; + } +#endif +private: + safe_bool(); + safe_bool(const safe_bool&); + void operator=(const safe_bool&); + ~safe_bool(); +}; + + } // namespace range_detail +} // namespace boost + +#endif // include guard diff --git a/include/boost/range/end.hpp b/include/boost/range/end.hpp index 3063c02..d5e6526 100644 --- a/include/boost/range/end.hpp +++ b/include/boost/range/end.hpp @@ -88,6 +88,9 @@ namespace range_detail } // namespace 'range_detail' #endif +namespace range_adl_barrier +{ + template< class T > inline BOOST_DEDUCED_TYPENAME range_iterator::type end( T& r ) { @@ -110,22 +113,24 @@ inline BOOST_DEDUCED_TYPENAME range_iterator::type end( const T& r ) return range_end( r ); } + } // namespace range_adl_barrier } // namespace 'boost' - - #endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING - namespace boost { - template< class T > - inline BOOST_DEDUCED_TYPENAME range_iterator::type - const_end( const T& r ) + namespace range_adl_barrier { - return boost::end( r ); - } -} + template< class T > + inline BOOST_DEDUCED_TYPENAME range_iterator::type + const_end( const T& r ) + { + return boost::range_adl_barrier::end( r ); + } + } // namespace range_adl_barrier + using namespace range_adl_barrier; +} // namespace boost #endif diff --git a/include/boost/range/iterator_range_core.hpp b/include/boost/range/iterator_range_core.hpp index ab1e80e..7664c2e 100755 --- a/include/boost/range/iterator_range_core.hpp +++ b/include/boost/range/iterator_range_core.hpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -81,7 +82,6 @@ namespace boost struct range_tag { }; struct const_range_tag { }; - } // iterator range template class -----------------------------------------// @@ -106,13 +106,14 @@ namespace boost template class iterator_range { + typedef range_detail::safe_bool< IteratorT iterator_range::* > safe_bool_t; protected: // Used by sub_range //! implementation class typedef iterator_range_detail::iterator_range_impl impl; public: - //! this type typedef iterator_range type; + typedef BOOST_DEDUCED_TYPENAME safe_bool_t::unspecified_bool_type unspecified_bool_type; //BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION(value_type); //! Encapsulated value type @@ -238,18 +239,15 @@ namespace boost return m_Begin == m_End; } -#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) - operator bool() const - { - return !empty(); - } -#else - typedef iterator (iterator_range::*unspecified_bool_type) () const; operator unspecified_bool_type() const { - return empty() ? 0: &iterator_range::end; + return safe_bool_t::to_unspecified_bool(m_Begin != m_End, &iterator_range::m_Begin); + } + + bool operator!() const + { + return empty(); } -#endif bool equal( const iterator_range& r ) const { diff --git a/include/boost/range/size.hpp b/include/boost/range/size.hpp index 2636905..4b4eebe 100644 --- a/include/boost/range/size.hpp +++ b/include/boost/range/size.hpp @@ -15,7 +15,7 @@ # pragma once #endif -#include +#include #include #include #include @@ -25,44 +25,25 @@ namespace boost { namespace range_detail { - template< class SinglePassRange > + template inline BOOST_DEDUCED_TYPENAME range_difference::type - size_impl(const SinglePassRange& rng, boost::single_pass_traversal_tag) - { - typedef BOOST_DEDUCED_TYPENAME range_difference::type diff_t; - - // A compilation error here will often indicate that an algorithm - // is attempting to use boost::size(rng) for a range that is not a - // model of the RandomAccessRange Concept and does not have a - // member size() function. - // The solution to this issue is to add a range_calculate_size() - // function for the range type that will be found via ADL. - return static_cast(rng.size()); - } - - template< class SinglePassRange > - inline BOOST_DEDUCED_TYPENAME range_difference::type - size_impl(const SinglePassRange& rng, boost::random_access_traversal_tag) + range_calculate_size(const SinglePassRange& rng) { BOOST_ASSERT( (boost::end(rng) - boost::begin(rng)) >= 0 && "reachability invariant broken!" ); return boost::end(rng) - boost::begin(rng); } - } // namespace range_detail - - template - inline BOOST_DEDUCED_TYPENAME range_difference::type - range_calculate_size(const SinglePassRange& rng) - { - typedef BOOST_DEDUCED_TYPENAME range_iterator::type iter_t; - typedef BOOST_DEDUCED_TYPENAME iterator_traversal::type traversal_tag; - return range_detail::size_impl(rng, traversal_tag()); } template inline BOOST_DEDUCED_TYPENAME range_difference::type size(const SinglePassRange& rng) { +#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) && \ + !BOOST_WORKAROUND(__GNUC__, < 3) \ + /**/ + using namespace range_detail; +#endif return range_calculate_size(rng); } diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index b52d869..e0087fb 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -59,6 +59,8 @@ test-suite range : [ range-test adaptor_test/sliced_example ] [ range-test adaptor_test/strided_example ] [ range-test adaptor_test/transformed_example ] + [ range-test adaptor_test/type_erased ] + [ range-test adaptor_test/type_erased_example ] [ range-test adaptor_test/uniqued_example ] [ range-test algorithm_test/adjacent_find ] [ range-test algorithm_test/binary_search ] @@ -131,11 +133,13 @@ test-suite range : [ range-test algorithm_example ] [ range-test array ] # [ range-test atl : $(VC71_ROOT)/atlmfc/include ] + [ range-test begin ] [ range-test combine ] [ range-test compat2 ] [ range-test compat3 ] [ range-test const_ranges ] [ range-test counting_range ] + [ range-test end ] [ range-test extension_mechanism ] [ range-test extension_size ] [ range-test has_range_iterator ] diff --git a/test/adaptor_test/strided.cpp b/test/adaptor_test/strided.cpp index 04f1f21..91beb81 100644 --- a/test/adaptor_test/strided.cpp +++ b/test/adaptor_test/strided.cpp @@ -128,10 +128,10 @@ namespace boost typedef boost::strided_range strided_range_t; strided_range_t rng( boost::adaptors::stride(c, 0) ); - typedef typename boost::range_iterator::type iter_t; + typedef BOOST_DEDUCED_TYPENAME boost::range_iterator::type iter_t; - iter_t first(boost::begin(c), 0, 0, boost::size(c)); - iter_t last(boost::end(c), 0, boost::size(c), boost::size(c)); + iter_t first(boost::begin(c), boost::begin(c), boost::end(c), 0); + iter_t last(boost::begin(c), boost::end(c), boost::end(c), 0); iter_t it = first; for (int i = 0; i < 10; ++i, ++it) @@ -206,16 +206,6 @@ namespace boost ++(this->base_reference()); } - bool equal(const strided_mock_iterator& other) const - { - return this->base() == other.base(); - } - - BOOST_DEDUCED_TYPENAME super_t::reference dereference() const - { - return *(this->base()); - } - friend class boost::iterator_core_access; }; diff --git a/test/adaptor_test/type_erased.cpp b/test/adaptor_test/type_erased.cpp new file mode 100644 index 0000000..fd3ee5f --- /dev/null +++ b/test/adaptor_test/type_erased.cpp @@ -0,0 +1,481 @@ +// Boost.Range library +// +// Copyright Neil Groves 2010. Use, modification and +// distribution is subject to 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) +// +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace boost_range_adaptor_type_erased_test +{ + class MockType + { + public: + MockType() + : m_x(0) + { + } + + MockType(int x) + : m_x(x) + { + } + + int get() const { return m_x; } + + inline bool operator==(const MockType& other) const + { + return m_x == other.m_x; + } + + inline bool operator!=(const MockType& other) const + { + return m_x != other.m_x; + } + + private: + int m_x; + }; + + inline std::ostream& operator<<(std::ostream& out, const MockType& obj) + { + out << obj.get(); + return out; + } + + template + void test_type_erased_impl(Container& c) + { + using namespace boost::adaptors; + typedef typename boost::range_value::type value_type; + typedef typename boost::adaptors::type_erased<> type_erased_t; + + + std::vector output; + + boost::push_back(output, boost::adaptors::type_erase(c, type_erased_t())); + + BOOST_CHECK_EQUAL_COLLECTIONS( output.begin(), output.end(), + c.begin(), c.end() ); + + output.clear(); + boost::push_back(output, c | type_erased_t()); + + BOOST_CHECK_EQUAL_COLLECTIONS( output.begin(), output.end(), + c.begin(), c.end() ); + } + + template + void test_const_and_mutable(Container& c) + { + test_type_erased_impl(c); + + const Container& const_c = c; + test_type_erased_impl(const_c); + } + + template + void test_driver() + { + using namespace boost::assign; + + typedef typename boost::range_value::type value_type; + + Container c; + test_const_and_mutable(c); + + c += value_type(1); + test_const_and_mutable(c); + + c += value_type(2); + test_const_and_mutable(c); + } + + void test_type_erased() + { + test_driver< std::list >(); + test_driver< std::vector >(); + + test_driver< std::list >(); + test_driver< std::vector >(); + } + + template< + class Traversal + , class Container + > + void test_writeable(Container&, boost::single_pass_traversal_tag) + {} + + template< + class Traversal + , class Container + > + void test_writeable(Container& source, boost::forward_traversal_tag) + { + using namespace boost::adaptors; + + typedef typename boost::range_value::type value_type; + typedef typename boost::range_difference::type difference_type; + typedef typename boost::range_reference::type mutable_reference_type; + typedef boost::any_range< + value_type + , Traversal + , mutable_reference_type + , difference_type + > mutable_any_range; + + mutable_any_range r = source | boost::adaptors::type_erased<>(); + std::vector output_test; + boost::fill(r, value_type(1)); + BOOST_CHECK_EQUAL( boost::distance(r), boost::distance(source) ); + std::vector reference_output(source.size(), value_type(1)); + BOOST_CHECK_EQUAL_COLLECTIONS( reference_output.begin(), reference_output.end(), + r.begin(), r.end() ); + + } + + template< + class Container + , class Traversal + , class Buffer + > + void test_type_erased_impl() + { + using namespace boost::adaptors; + + typedef Buffer buffer_type; + + typedef typename boost::range_value::type value_type; + + typedef typename boost::any_range_type_generator< + Container + , boost::use_default + , Traversal + , boost::use_default + , boost::use_default + , Buffer + >::type mutable_any_range; + + typedef typename boost::any_range_type_generator< + const Container + , boost::use_default + , Traversal + , boost::use_default + , boost::use_default + , Buffer + >::type const_any_range; + + typedef boost::adaptors::type_erased< + boost::use_default + , Traversal + , boost::use_default + , boost::use_default + , Buffer + > type_erased_t; + + Container source; + for (int i = 0; i < 10; ++i) + source.push_back(value_type(i)); + + mutable_any_range r(source); + BOOST_CHECK_EQUAL_COLLECTIONS( source.begin(), source.end(), + r.begin(), r.end() ); + + r = mutable_any_range(); + BOOST_CHECK_EQUAL( r.empty(), true ); + + r = source | type_erased_t(); + BOOST_CHECK_EQUAL_COLLECTIONS( source.begin(), source.end(), + r.begin(), r.end() ); + r = mutable_any_range(); + + r = boost::adaptors::type_erase(source, type_erased_t()); + BOOST_CHECK_EQUAL_COLLECTIONS( source.begin(), source.end(), + r.begin(), r.end() ); + r = mutable_any_range(); + + test_writeable(source, Traversal()); + + // convert and construct a const any_range from a mutable source + // range + const_any_range cr(source); + BOOST_CHECK_EQUAL_COLLECTIONS( source.begin(), source.end(), + cr.begin(), cr.end() ); + // assign an empty range and ensure that this correctly results + // in an empty range. This is important for the validity of + // the rest of the tests. + cr = const_any_range(); + BOOST_CHECK_EQUAL( cr.empty(), true ); + + // Test the pipe type_erased adaptor from a constant source + // range to a constant any_range + const Container& const_source = source; + cr = const_any_range(); + cr = const_source | type_erased_t(); + BOOST_CHECK_EQUAL_COLLECTIONS( const_source.begin(), const_source.end(), + cr.begin(), cr.end() ); + + // Test the pipe type erased adaptor from a mutable source + // range to a constant any_range + cr = const_any_range(); + cr = source | type_erased_t(); + BOOST_CHECK_EQUAL_COLLECTIONS( source.begin(), source.end(), + cr.begin(), cr.end() ); + + // Use the function form of the type_erase adaptor from a constant + // source range + cr = const_any_range(); + cr = boost::adaptors::type_erase(const_source, type_erased_t()); + BOOST_CHECK_EQUAL_COLLECTIONS( const_source.begin(), const_source.end(), + cr.begin(), cr.end() ); + + // Assignment from mutable to const... + cr = const_any_range(); + cr = r; + BOOST_CHECK_EQUAL_COLLECTIONS( cr.begin(), cr.end(), + r.begin(), r.end() ); + + // Converting copy from mutable to const... + cr = const_any_range(); + cr = const_any_range(r); + BOOST_CHECK_EQUAL_COLLECTIONS( cr.begin(), cr.end(), + r.begin(), r.end() ); + } + + template< + class Container + , class Traversal + , class Buffer + > + class test_type_erased_impl_fn + { + public: + typedef void result_type; + void operator()() + { + test_type_erased_impl< Container, Traversal, Buffer >(); + } + }; + + template< + class Container + , class Traversal + > + void test_type_erased_exercise_buffer_types() + { + using boost::any_iterator_default_buffer; + using boost::any_iterator_buffer; + using boost::any_iterator_heap_only_buffer; + using boost::any_iterator_stack_only_buffer; + + test_type_erased_impl_fn< Container, Traversal, any_iterator_default_buffer >()(); + test_type_erased_impl_fn< Container, Traversal, any_iterator_heap_only_buffer >()(); + test_type_erased_impl_fn< Container, Traversal, any_iterator_buffer<1> >()(); + test_type_erased_impl_fn< Container, Traversal, any_iterator_buffer<2> >()(); + test_type_erased_impl_fn< Container, Traversal, any_iterator_buffer<32> >()(); + test_type_erased_impl_fn< Container, Traversal, any_iterator_buffer<64> >()(); + test_type_erased_impl_fn< Container, Traversal, any_iterator_buffer<128> >()(); + test_type_erased_impl_fn< Container, Traversal, any_iterator_stack_only_buffer<128> >()(); + } + + void test_type_erased_single_pass() + { + test_type_erased_exercise_buffer_types< std::list, boost::single_pass_traversal_tag >(); + test_type_erased_exercise_buffer_types< std::deque, boost::single_pass_traversal_tag >(); + test_type_erased_exercise_buffer_types< std::vector, boost::single_pass_traversal_tag >(); + + test_type_erased_exercise_buffer_types< std::list, boost::single_pass_traversal_tag >(); + test_type_erased_exercise_buffer_types< std::deque, boost::single_pass_traversal_tag >(); + test_type_erased_exercise_buffer_types< std::vector, boost::single_pass_traversal_tag >(); + } + + void test_type_erased_forward() + { + test_type_erased_exercise_buffer_types< std::list, boost::forward_traversal_tag >(); + test_type_erased_exercise_buffer_types< std::deque, boost::forward_traversal_tag >(); + test_type_erased_exercise_buffer_types< std::vector, boost::forward_traversal_tag >(); + + test_type_erased_exercise_buffer_types< std::list, boost::forward_traversal_tag >(); + test_type_erased_exercise_buffer_types< std::deque, boost::forward_traversal_tag >(); + test_type_erased_exercise_buffer_types< std::vector, boost::forward_traversal_tag >(); + } + + void test_type_erased_bidirectional() + { + test_type_erased_exercise_buffer_types< std::list, boost::bidirectional_traversal_tag >(); + test_type_erased_exercise_buffer_types< std::deque, boost::bidirectional_traversal_tag >(); + test_type_erased_exercise_buffer_types< std::vector, boost::bidirectional_traversal_tag >(); + + test_type_erased_exercise_buffer_types< std::list, boost::bidirectional_traversal_tag >(); + test_type_erased_exercise_buffer_types< std::deque, boost::bidirectional_traversal_tag >(); + test_type_erased_exercise_buffer_types< std::vector, boost::bidirectional_traversal_tag >(); + } + + void test_type_erased_random_access() + { + test_type_erased_exercise_buffer_types< std::deque, boost::random_access_traversal_tag >(); + test_type_erased_exercise_buffer_types< std::vector, boost::random_access_traversal_tag >(); + + test_type_erased_exercise_buffer_types< std::deque, boost::random_access_traversal_tag >(); + test_type_erased_exercise_buffer_types< std::vector, boost::random_access_traversal_tag >(); + } + + void test_type_erased_multiple_different_template_parameter_conversion() + { + typedef boost::any_range< + int + , boost::random_access_traversal_tag + , int& + , std::ptrdiff_t + > source_range_type; + + typedef boost::any_range< + int + , boost::single_pass_traversal_tag + , const int& + , std::ptrdiff_t + > target_range_type; + + source_range_type source; + + // Converting via construction + target_range_type t1(source); + + // Converting via assignment + target_range_type t2; + t2 = source; + + // Converting via construction to a type with a reference type + // that is a value + typedef boost::any_range< + int + , boost::single_pass_traversal_tag + , int + , std::ptrdiff_t + > target_range2_type; + + target_range2_type t3(source); + target_range2_type t4; + t4 = source; + } + + template< + class Traversal + , class ValueType + , class SourceValueType + , class SourceReference + , class TargetValueType + , class TargetReference + > + void test_type_erased_mix_values_impl() + { + typedef std::vector< ValueType > Container; + + typedef typename boost::any_range_type_generator< + Container + , SourceValueType + , Traversal + , SourceReference + >::type source_type; + + typedef typename boost::any_range_type_generator< + Container + , TargetValueType + , Traversal + , TargetReference + >::type target_type; + + Container test_data; + for (int i = 0; i < 10; ++i) + test_data.push_back(i); + + const source_type source_data(test_data); + target_type t1(source_data); + BOOST_CHECK_EQUAL_COLLECTIONS( source_data.begin(), source_data.end(), + t1.begin(), t1.end() ); + + target_type t2; + t2 = source_data; + BOOST_CHECK_EQUAL_COLLECTIONS( source_data.begin(), source_data.end(), + t2.begin(), t2.end() ); + } + + template + void test_type_erased_mix_values_driver() + { + test_type_erased_mix_values_impl< Traversal, int, char, const int&, short, const int& >(); + test_type_erased_mix_values_impl< Traversal, int, int*, const int&, char, const int& >(); + test_type_erased_mix_values_impl< Traversal, MockType, char, const MockType&, short, const MockType& >(); + + // In fact value type should have no effect in the eligibility + // for conversion, hence we should be able to convert it + // completely backwards! + test_type_erased_mix_values_impl< Traversal, int, short, const int&, char, const int& >(); + test_type_erased_mix_values_impl< Traversal, int, char, const int&, int*, const int& >(); + } + + void test_type_erased_mix_values() + { + test_type_erased_mix_values_driver< boost::single_pass_traversal_tag >(); + test_type_erased_mix_values_driver< boost::forward_traversal_tag >(); + test_type_erased_mix_values_driver< boost::bidirectional_traversal_tag >(); + test_type_erased_mix_values_driver< boost::random_access_traversal_tag >(); + } + + void test_type_erased_operator_brackets() + { + typedef boost::adaptors::type_erased<> type_erased_t; + + std::vector c; + for (int i = 0; i < 10; ++i) + c.push_back(i); + + typedef boost::any_range< + int + , boost::random_access_traversal_tag + , int + , boost::range_difference< std::vector >::type + , boost::use_default + > any_range_type; + + any_range_type rng = c | type_erased_t(); + + for (int i = 0; i < 10; ++i) + { + BOOST_CHECK_EQUAL( rng[i], i ); + } + } +} + +boost::unit_test::test_suite* +init_unit_test_suite(int argc, char* argv[]) +{ + boost::unit_test::test_suite* test + = BOOST_TEST_SUITE( "RangeTestSuite.adaptor.type_erased" ); + + test->add( BOOST_TEST_CASE( &boost_range_adaptor_type_erased_test::test_type_erased ) ); + test->add( BOOST_TEST_CASE( &boost_range_adaptor_type_erased_test::test_type_erased_single_pass ) ); + test->add( BOOST_TEST_CASE( &boost_range_adaptor_type_erased_test::test_type_erased_forward ) ); + test->add( BOOST_TEST_CASE( &boost_range_adaptor_type_erased_test::test_type_erased_bidirectional ) ); + test->add( BOOST_TEST_CASE( &boost_range_adaptor_type_erased_test::test_type_erased_random_access ) ); + test->add( BOOST_TEST_CASE( &boost_range_adaptor_type_erased_test::test_type_erased_multiple_different_template_parameter_conversion ) ); + test->add( BOOST_TEST_CASE( &boost_range_adaptor_type_erased_test::test_type_erased_mix_values ) ); + test->add( BOOST_TEST_CASE( &boost_range_adaptor_type_erased_test::test_type_erased_operator_brackets ) ); + + return test; +} diff --git a/test/adaptor_test/type_erased_example.cpp b/test/adaptor_test/type_erased_example.cpp new file mode 100644 index 0000000..754fba6 --- /dev/null +++ b/test/adaptor_test/type_erased_example.cpp @@ -0,0 +1,115 @@ +// Boost.Range library +// +// Copyright Neil Groves 2010. Use, modification and +// distribution is subject to 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) +// +// +// For more information, see http://www.boost.org/libs/range/ +// +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace +{ + namespace boost_range_test + { + namespace type_erased_example + { + +// The client interface from an OO perspective merely requires a sequence +// of integers that can be forward traversed +typedef boost::any_range< + int + , boost::forward_traversal_tag + , int + , std::ptrdiff_t +> integer_range; + +namespace server +{ + void display_integers(const integer_range& rng) + { + boost::copy(rng, + std::ostream_iterator(std::cout, ",")); + + std::cout << std::endl; + } +} + +namespace client +{ + void run() + { + using namespace boost::assign; + using namespace boost::adaptors; + + // Under most conditions one would simply use an appropriate + // any_range as a function parameter. The type_erased adaptor + // is often superfluous. However because the type_erased + // adaptor is applied to a range, we can use default template + // arguments that are generated in conjunction with the + // range type to which we are applying the adaptor. + + std::vector input; + input += 1,2,3,4,5; + + // Note that this call is to a non-template function + server::display_integers(input); + + std::list input2; + input2 += 6,7,8,9,10; + + // Note that this call is to the same non-tempate function + server::display_integers(input2); + + input2.clear(); + input2 += 11,12,13,14,15; + + // Calling using the adaptor looks like this: + // Notice that here I have a type_erased that would be a + // bidirectional_traversal_tag, but this is convertible + // to the forward_traversal_tag equivalent hence this + // works. + server::display_integers(input2 | type_erased<>()); + + // However we may simply wish to define an adaptor that + // takes a range and makes it into an appropriate + // forward_traversal any_range... + typedef boost::adaptors::type_erased< + boost::use_default + , boost::forward_traversal_tag + > type_erased_forward; + + // This adaptor can turn other containers with different + // value_types and reference_types into the appropriate + // any_range. + + server::display_integers(input2 | type_erased_forward()); + } +} + + } // namespace type_erased_example + } // namespace boost_range_test +} // anonymous namespace + +boost::unit_test::test_suite* +init_unit_test_suite(int argc, char* argv[]) +{ + boost::unit_test::test_suite* test + = BOOST_TEST_SUITE( "RangeTestSuite.adaptor.type_erased_example" ); + + test->add( BOOST_TEST_CASE( &boost_range_test::type_erased_example::client::run) ); + + return test; +} diff --git a/test/algorithm_test/count_if.cpp b/test/algorithm_test/count_if.cpp index a2e8983..e028741 100644 --- a/test/algorithm_test/count_if.cpp +++ b/test/algorithm_test/count_if.cpp @@ -33,6 +33,7 @@ namespace boost using namespace boost::assign; typedef equal_to_x pred_t; + typedef BOOST_DEDUCED_TYPENAME std::iterator_traits::difference_type diff_t; Container cont; const Container& cref_cont = cont; @@ -72,9 +73,9 @@ namespace boost BOOST_CHECK_EQUAL( 0u, boost::count_if(cref_cont, false_predicate()) ); BOOST_CHECK_EQUAL( 0u, boost::count_if(boost::make_iterator_range(cont), false_predicate()) ); - BOOST_CHECK_EQUAL( boost::size(cont), boost::count_if(cont, true_predicate()) ); - BOOST_CHECK_EQUAL( boost::size(cont), boost::count_if(cref_cont, true_predicate()) ); - BOOST_CHECK_EQUAL( boost::size(cont), boost::count_if(boost::make_iterator_range(cont), true_predicate()) ); + BOOST_CHECK_EQUAL( static_cast(cont.size()), boost::count_if(cont, true_predicate()) ); + BOOST_CHECK_EQUAL( static_cast(cont.size()), boost::count_if(cref_cont, true_predicate()) ); + BOOST_CHECK_EQUAL( static_cast(cont.size()), boost::count_if(boost::make_iterator_range(cont), true_predicate()) ); } void test_count_if() diff --git a/test/algorithm_test/find.cpp b/test/algorithm_test/find.cpp index 6eb1528..d785ac8 100644 --- a/test/algorithm_test/find.cpp +++ b/test/algorithm_test/find.cpp @@ -22,85 +22,82 @@ #include #include -namespace boost +namespace boost_range_test_algorithm_find { - namespace + class find_test_policy { - class find_test_policy + public: + template + BOOST_DEDUCED_TYPENAME boost::range_iterator::type + test_iter(Container& cont) { - public: - template - BOOST_DEDUCED_TYPENAME range_iterator::type - test_iter(Container& cont) + typedef BOOST_DEDUCED_TYPENAME boost::range_iterator::type iter_t; + iter_t result = boost::find(cont, 3); + iter_t result2 = boost::find(boost::make_iterator_range(cont), 3); + BOOST_CHECK( result == result2 ); + return result; + } + + template + struct test_range + { + template + BOOST_DEDUCED_TYPENAME boost::range_return::type + operator()(Policy&, Container& cont) { - typedef BOOST_DEDUCED_TYPENAME range_iterator::type iter_t; - iter_t result = boost::find(cont, 3); - iter_t result2 = boost::find(boost::make_iterator_range(cont), 3); + typedef BOOST_DEDUCED_TYPENAME boost::range_return::type result_t; + result_t result = boost::find(cont, 3); + result_t result2 = boost::find(boost::make_iterator_range(cont), 3); BOOST_CHECK( result == result2 ); return result; } - - template - struct test_range - { - template - BOOST_DEDUCED_TYPENAME range_return::type - operator()(Policy&, Container& cont) - { - typedef BOOST_DEDUCED_TYPENAME range_return::type result_t; - result_t result = boost::find(cont, 3); - result_t result2 = boost::find(boost::make_iterator_range(cont), 3); - BOOST_CHECK( result == result2 ); - return result; - } - }; - - template - BOOST_DEDUCED_TYPENAME range_iterator::type - reference(Container& cont) - { - return std::find(cont.begin(), cont.end(), 3); - } }; template - void test_find_container() + BOOST_DEDUCED_TYPENAME boost::range_iterator::type + reference(Container& cont) { - using namespace boost::assign; - - typedef BOOST_DEDUCED_TYPENAME remove_const::type container_t; - - range_test::range_return_test_driver test_driver; - - container_t mcont; - Container& cont = mcont; - test_driver(cont, find_test_policy()); - - mcont.clear(); - mcont += 1; - test_driver(cont, find_test_policy()); - - mcont.clear(); - mcont += 1,2,3,4,5,6,7,8,9; - test_driver(cont, find_test_policy()); + return std::find(cont.begin(), cont.end(), 3); } + }; - void test_find() - { - test_find_container< std::vector >(); - test_find_container< std::list >(); - test_find_container< std::deque >(); + template + void test_find_container() + { + using namespace boost::assign; - test_find_container< const std::vector >(); - test_find_container< const std::list >(); - test_find_container< const std::deque >(); + typedef BOOST_DEDUCED_TYPENAME boost::remove_const::type container_t; - std::vector vi; - const std::vector& cvi = vi; - std::vector::const_iterator it = boost::find(vi, 0); - std::vector::const_iterator it2 = boost::find(cvi, 0); - BOOST_CHECK( it == it2 ); - } + boost::range_test::range_return_test_driver test_driver; + + container_t mcont; + Container& cont = mcont; + test_driver(cont, find_test_policy()); + + mcont.clear(); + mcont += 1; + test_driver(cont, find_test_policy()); + + mcont.clear(); + mcont += 1,2,3,4,5,6,7,8,9; + test_driver(cont, find_test_policy()); + } + + void test_find() + { + test_find_container< std::vector >(); + test_find_container< std::list >(); + test_find_container< std::deque >(); + + test_find_container< const std::vector >(); + test_find_container< const std::list >(); + test_find_container< const std::deque >(); + + std::vector vi; + const std::vector& cvi = vi; + std::vector::const_iterator it = boost::find(vi, 0); + std::vector::const_iterator it2 = boost::find(cvi, 0); + BOOST_CHECK( it == it2 ); } } @@ -110,7 +107,7 @@ init_unit_test_suite(int argc, char* argv[]) boost::unit_test::test_suite* test = BOOST_TEST_SUITE( "RangeTestSuite.algorithm.find" ); - test->add( BOOST_TEST_CASE( &boost::test_find ) ); + test->add( BOOST_TEST_CASE( &boost_range_test_algorithm_find::test_find ) ); return test; } diff --git a/test/algorithm_test/find_end.cpp b/test/algorithm_test/find_end.cpp index 0592d5f..b4d77a0 100644 --- a/test/algorithm_test/find_end.cpp +++ b/test/algorithm_test/find_end.cpp @@ -21,173 +21,170 @@ #include #include -namespace boost +namespace boost_range_test_algorithm_find_end { - namespace + template + class find_end_test_policy { - template - class find_end_test_policy + typedef Container2 container2_t; + public: + explicit find_end_test_policy(const Container2& cont) + : m_cont(cont) { - typedef Container2 container2_t; - public: - explicit find_end_test_policy(const Container2& cont) - : m_cont(cont) - { - } + } - container2_t cont() { return m_cont; } + container2_t cont() { return m_cont; } - template - BOOST_DEDUCED_TYPENAME range_iterator::type - test_iter(Container& cont) + template + BOOST_DEDUCED_TYPENAME boost::range_iterator::type + test_iter(Container& cont) + { + typedef BOOST_DEDUCED_TYPENAME boost::range_iterator::type iter_t; + iter_t result = boost::find_end(cont, m_cont); + BOOST_CHECK( result == boost::find_end(boost::make_iterator_range(cont), m_cont) ); + BOOST_CHECK( result == boost::find_end(cont, boost::make_iterator_range(m_cont)) ); + BOOST_CHECK( result == boost::find_end(boost::make_iterator_range(cont), boost::make_iterator_range(m_cont)) ); + return result; + } + + template + struct test_range + { + template + BOOST_DEDUCED_TYPENAME boost::range_return::type + operator()(Policy& policy, Container& cont) { - typedef BOOST_DEDUCED_TYPENAME range_iterator::type iter_t; - iter_t result = boost::find_end(cont, m_cont); - BOOST_CHECK( result == boost::find_end(boost::make_iterator_range(cont), m_cont) ); - BOOST_CHECK( result == boost::find_end(cont, boost::make_iterator_range(m_cont)) ); - BOOST_CHECK( result == boost::find_end(boost::make_iterator_range(cont), boost::make_iterator_range(m_cont)) ); + typedef BOOST_DEDUCED_TYPENAME boost::range_return::type result_t; + result_t result = boost::find_end(cont, policy.cont()); + BOOST_CHECK( result == boost::find_end(boost::make_iterator_range(cont), policy.cont()) ); + BOOST_CHECK( result == boost::find_end(cont, boost::make_iterator_range(policy.cont())) ); + BOOST_CHECK( result == boost::find_end(boost::make_iterator_range(cont), + boost::make_iterator_range(policy.cont())) ); return result; } - - template - struct test_range - { - template - BOOST_DEDUCED_TYPENAME range_return::type - operator()(Policy& policy, Container& cont) - { - typedef BOOST_DEDUCED_TYPENAME range_return::type result_t; - result_t result = boost::find_end(cont, policy.cont()); - BOOST_CHECK( result == boost::find_end(boost::make_iterator_range(cont), policy.cont()) ); - BOOST_CHECK( result == boost::find_end(cont, boost::make_iterator_range(policy.cont())) ); - BOOST_CHECK( result == boost::find_end(boost::make_iterator_range(cont), - boost::make_iterator_range(policy.cont())) ); - return result; - } - }; - - template - BOOST_DEDUCED_TYPENAME range_iterator::type - reference(Container& cont) - { - return std::find_end(cont.begin(), cont.end(), - m_cont.begin(), m_cont.end()); - } - - private: - Container2 m_cont; }; - template - class find_end_pred_test_policy + template + BOOST_DEDUCED_TYPENAME boost::range_iterator::type + reference(Container& cont) { - typedef Container2 container2_t; - public: - explicit find_end_pred_test_policy(const Container2& cont) - : m_cont(cont) + return std::find_end(cont.begin(), cont.end(), + m_cont.begin(), m_cont.end()); + } + + private: + Container2 m_cont; + }; + + template + class find_end_pred_test_policy + { + typedef Container2 container2_t; + public: + explicit find_end_pred_test_policy(const Container2& cont) + : m_cont(cont) + { + } + + container2_t& cont() { return m_cont; } + BinaryPredicate& pred() { return m_pred; } + + template + BOOST_DEDUCED_TYPENAME boost::range_iterator::type + test_iter(Container& cont) + { + typedef BOOST_DEDUCED_TYPENAME boost::range_iterator::type iter_t; + iter_t it = boost::find_end(cont, m_cont, m_pred); + BOOST_CHECK( it == boost::find_end(boost::make_iterator_range(cont), m_cont, m_pred) ); + BOOST_CHECK( it == boost::find_end(cont, boost::make_iterator_range(m_cont), m_pred) ); + BOOST_CHECK( it == boost::find_end(boost::make_iterator_range(cont), boost::make_iterator_range(m_cont), m_pred) ); + return it; + } + + template + struct test_range + { + template + BOOST_DEDUCED_TYPENAME boost::range_return::type + operator()(Policy& policy, Container& cont) { + typedef BOOST_DEDUCED_TYPENAME boost::range_return::type result_t; + result_t result = boost::find_end(cont, policy.cont(), policy.pred()); + BOOST_CHECK( result == boost::find_end(boost::make_iterator_range(cont), policy.cont(), policy.pred()) ); + BOOST_CHECK( result == boost::find_end(cont, boost::make_iterator_range(policy.cont()), policy.pred()) ); + BOOST_CHECK( result == boost::find_end(boost::make_iterator_range(cont), + boost::make_iterator_range(policy.cont()), policy.pred()) ); + return boost::find_end(cont, policy.cont(), policy.pred()); } - - container2_t& cont() { return m_cont; } - BinaryPredicate& pred() { return m_pred; } - - template - BOOST_DEDUCED_TYPENAME range_iterator::type - test_iter(Container& cont) - { - typedef BOOST_DEDUCED_TYPENAME range_iterator::type iter_t; - iter_t it = boost::find_end(cont, m_cont, m_pred); - BOOST_CHECK( it == boost::find_end(boost::make_iterator_range(cont), m_cont, m_pred) ); - BOOST_CHECK( it == boost::find_end(cont, boost::make_iterator_range(m_cont), m_pred) ); - BOOST_CHECK( it == boost::find_end(boost::make_iterator_range(cont), boost::make_iterator_range(m_cont), m_pred) ); - return it; - } - - template - struct test_range - { - template - BOOST_DEDUCED_TYPENAME range_return::type - operator()(Policy& policy, Container& cont) - { - typedef BOOST_DEDUCED_TYPENAME range_return::type result_t; - result_t result = boost::find_end(cont, policy.cont(), policy.pred()); - BOOST_CHECK( result == boost::find_end(boost::make_iterator_range(cont), policy.cont(), policy.pred()) ); - BOOST_CHECK( result == boost::find_end(cont, boost::make_iterator_range(policy.cont()), policy.pred()) ); - BOOST_CHECK( result == boost::find_end(boost::make_iterator_range(cont), - boost::make_iterator_range(policy.cont()), policy.pred()) ); - return boost::find_end(cont, policy.cont(), policy.pred()); - } - }; - - template - BOOST_DEDUCED_TYPENAME range_iterator::type - reference(Container& cont) - { - return std::find_end(cont.begin(), cont.end(), - m_cont.begin(), m_cont.end(), - m_pred); - } - - private: - Container2 m_cont; - BinaryPredicate m_pred; }; - template - void run_tests(Container1& cont1, Container2& cont2) + template + BOOST_DEDUCED_TYPENAME boost::range_iterator::type + reference(Container& cont) { - range_test::range_return_test_driver test_driver; - test_driver(cont1, find_end_test_policy(cont2)); - test_driver(cont1, find_end_pred_test_policy >(cont2)); - test_driver(cont2, find_end_pred_test_policy >(cont2)); + return std::find_end(cont.begin(), cont.end(), + m_cont.begin(), m_cont.end(), + m_pred); } - template - void test_find_end_impl() - { - using namespace boost::assign; + private: + Container2 m_cont; + BinaryPredicate m_pred; + }; - typedef BOOST_DEDUCED_TYPENAME remove_const::type container1_t; - typedef BOOST_DEDUCED_TYPENAME remove_const::type container2_t; + template + void run_tests(Container1& cont1, Container2& cont2) + { + boost::range_test::range_return_test_driver test_driver; + test_driver(cont1, find_end_test_policy(cont2)); + test_driver(cont1, find_end_pred_test_policy >(cont2)); + test_driver(cont2, find_end_pred_test_policy >(cont2)); + } - container1_t mcont1; - Container1& cont1 = mcont1; - container2_t mcont2; - Container2& cont2 = mcont2; + template + void test_find_end_impl() + { + using namespace boost::assign; - run_tests(cont1, cont2); + typedef BOOST_DEDUCED_TYPENAME boost::remove_const::type container1_t; + typedef BOOST_DEDUCED_TYPENAME boost::remove_const::type container2_t; - mcont1 += 1; - run_tests(cont1, cont2); + container1_t mcont1; + Container1& cont1 = mcont1; + container2_t mcont2; + Container2& cont2 = mcont2; - mcont2 += 1; - run_tests(cont1, cont2); + run_tests(cont1, cont2); - mcont1 += 2,3,4,5,6,7,8,9; - mcont2 += 2,3,4; - run_tests(cont1, cont2); + mcont1 += 1; + run_tests(cont1, cont2); - mcont2.clear(); - mcont2 += 7,8,9; - run_tests(cont1, cont2); - } + mcont2 += 1; + run_tests(cont1, cont2); - void test_find_end() - { - test_find_end_impl< std::vector, std::vector >(); - test_find_end_impl< std::list, std::list >(); - test_find_end_impl< std::deque, std::deque >(); - test_find_end_impl< const std::vector, const std::vector >(); - test_find_end_impl< const std::list, const std::list >(); - test_find_end_impl< const std::deque, const std::deque >(); - test_find_end_impl< const std::vector, const std::list >(); - test_find_end_impl< const std::list, const std::vector >(); - test_find_end_impl< const std::vector, std::list >(); - test_find_end_impl< const std::list, std::vector >(); - test_find_end_impl< std::vector, std::list >(); - test_find_end_impl< std::list, std::vector >(); - } + mcont1 += 2,3,4,5,6,7,8,9; + mcont2 += 2,3,4; + run_tests(cont1, cont2); + + mcont2.clear(); + mcont2 += 7,8,9; + run_tests(cont1, cont2); + } + + void test_find_end() + { + test_find_end_impl< std::vector, std::vector >(); + test_find_end_impl< std::list, std::list >(); + test_find_end_impl< std::deque, std::deque >(); + test_find_end_impl< const std::vector, const std::vector >(); + test_find_end_impl< const std::list, const std::list >(); + test_find_end_impl< const std::deque, const std::deque >(); + test_find_end_impl< const std::vector, const std::list >(); + test_find_end_impl< const std::list, const std::vector >(); + test_find_end_impl< const std::vector, std::list >(); + test_find_end_impl< const std::list, std::vector >(); + test_find_end_impl< std::vector, std::list >(); + test_find_end_impl< std::list, std::vector >(); } } @@ -197,7 +194,7 @@ init_unit_test_suite(int argc, char* argv[]) boost::unit_test::test_suite* test = BOOST_TEST_SUITE( "RangeTestSuite.algorithm.find_end" ); - test->add( BOOST_TEST_CASE( &boost::test_find_end ) ); + test->add( BOOST_TEST_CASE( &boost_range_test_algorithm_find_end::test_find_end ) ); return test; } diff --git a/test/algorithm_test/find_first_of.cpp b/test/algorithm_test/find_first_of.cpp index c96d36a..296b8fc 100644 --- a/test/algorithm_test/find_first_of.cpp +++ b/test/algorithm_test/find_first_of.cpp @@ -21,171 +21,168 @@ #include #include -namespace boost +namespace boost_range_test_algorithm_find_first_of { - namespace + template + class find_first_of_test_policy { - template - class find_first_of_test_policy + typedef Container2 container2_t; + public: + explicit find_first_of_test_policy(const Container2& cont) + : m_cont(cont) { - typedef Container2 container2_t; - public: - explicit find_first_of_test_policy(const Container2& cont) - : m_cont(cont) - { - } + } - container2_t& cont() { return m_cont; } + container2_t& cont() { return m_cont; } - template - BOOST_DEDUCED_TYPENAME range_iterator::type - test_iter(Container& cont) + template + BOOST_DEDUCED_TYPENAME boost::range_iterator::type + test_iter(Container& cont) + { + typedef BOOST_DEDUCED_TYPENAME boost::range_iterator::type iter_t; + iter_t result = boost::find_first_of(cont, m_cont); + BOOST_CHECK( result == boost::find_first_of(boost::make_iterator_range(cont), m_cont) ); + BOOST_CHECK( result == boost::find_first_of(cont, boost::make_iterator_range(m_cont)) ); + BOOST_CHECK( result == boost::find_first_of(boost::make_iterator_range(cont), boost::make_iterator_range(m_cont)) ); + return result; + } + + template + struct test_range + { + template + BOOST_DEDUCED_TYPENAME boost::range_return::type + operator()(Policy& policy, Container& cont) { - typedef BOOST_DEDUCED_TYPENAME range_iterator::type iter_t; - iter_t result = boost::find_first_of(cont, m_cont); - BOOST_CHECK( result == boost::find_first_of(boost::make_iterator_range(cont), m_cont) ); - BOOST_CHECK( result == boost::find_first_of(cont, boost::make_iterator_range(m_cont)) ); - BOOST_CHECK( result == boost::find_first_of(boost::make_iterator_range(cont), boost::make_iterator_range(m_cont)) ); + typedef BOOST_DEDUCED_TYPENAME boost::range_return::type result_t; + result_t result = boost::find_first_of(cont, policy.cont()); + BOOST_CHECK( result == boost::find_first_of(boost::make_iterator_range(cont), policy.cont()) ); + BOOST_CHECK( result == boost::find_first_of(cont, boost::make_iterator_range(policy.cont())) ); + BOOST_CHECK( result == boost::find_first_of(boost::make_iterator_range(cont), boost::make_iterator_range(policy.cont())) ); return result; } - - template - struct test_range - { - template - BOOST_DEDUCED_TYPENAME range_return::type - operator()(Policy& policy, Container& cont) - { - typedef BOOST_DEDUCED_TYPENAME range_return::type result_t; - result_t result = boost::find_first_of(cont, policy.cont()); - BOOST_CHECK( result == boost::find_first_of(boost::make_iterator_range(cont), policy.cont()) ); - BOOST_CHECK( result == boost::find_first_of(cont, boost::make_iterator_range(policy.cont())) ); - BOOST_CHECK( result == boost::find_first_of(boost::make_iterator_range(cont), boost::make_iterator_range(policy.cont())) ); - return result; - } - }; - - template - BOOST_DEDUCED_TYPENAME range_iterator::type - reference(Container& cont) - { - return std::find_first_of(cont.begin(), cont.end(), - m_cont.begin(), m_cont.end()); - } - - private: - Container2 m_cont; }; - template - class find_first_of_pred_test_policy + template + BOOST_DEDUCED_TYPENAME boost::range_iterator::type + reference(Container& cont) { - typedef Container2 container2_t; - public: - explicit find_first_of_pred_test_policy(const Container2& cont) - : m_cont(cont) - { - } + return std::find_first_of(cont.begin(), cont.end(), + m_cont.begin(), m_cont.end()); + } - container2_t& cont() { return m_cont; } - BinaryPredicate& pred() { return m_pred; } + private: + Container2 m_cont; + }; - template - BOOST_DEDUCED_TYPENAME range_iterator::type - test_iter(Container& cont) + template + class find_first_of_pred_test_policy + { + typedef Container2 container2_t; + public: + explicit find_first_of_pred_test_policy(const Container2& cont) + : m_cont(cont) + { + } + + container2_t& cont() { return m_cont; } + BinaryPredicate& pred() { return m_pred; } + + template + BOOST_DEDUCED_TYPENAME boost::range_iterator::type + test_iter(Container& cont) + { + typedef BOOST_DEDUCED_TYPENAME boost::range_iterator::type iter_t; + iter_t result = boost::find_first_of(cont, m_cont, m_pred); + BOOST_CHECK( result == boost::find_first_of(boost::make_iterator_range(cont), m_cont, m_pred) ); + BOOST_CHECK( result == boost::find_first_of(cont, boost::make_iterator_range(m_cont), m_pred) ); + BOOST_CHECK( result == boost::find_first_of(boost::make_iterator_range(cont), boost::make_iterator_range(m_cont), m_pred) ); + return result; + } + + template + struct test_range + { + template + BOOST_DEDUCED_TYPENAME boost::range_return::type + operator()(Policy& policy, Container& cont) { - typedef BOOST_DEDUCED_TYPENAME range_iterator::type iter_t; - iter_t result = boost::find_first_of(cont, m_cont, m_pred); - BOOST_CHECK( result == boost::find_first_of(boost::make_iterator_range(cont), m_cont, m_pred) ); - BOOST_CHECK( result == boost::find_first_of(cont, boost::make_iterator_range(m_cont), m_pred) ); - BOOST_CHECK( result == boost::find_first_of(boost::make_iterator_range(cont), boost::make_iterator_range(m_cont), m_pred) ); + typedef BOOST_DEDUCED_TYPENAME boost::range_return::type result_t; + result_t result = boost::find_first_of(cont, policy.cont(), policy.pred()); + BOOST_CHECK( result == boost::find_first_of(boost::make_iterator_range(cont), policy.cont(), policy.pred()) ); + BOOST_CHECK( result == boost::find_first_of(cont, boost::make_iterator_range(policy.cont()), policy.pred()) ); + BOOST_CHECK( result == boost::find_first_of(boost::make_iterator_range(cont), boost::make_iterator_range(policy.cont()), policy.pred()) ); return result; } - - template - struct test_range - { - template - BOOST_DEDUCED_TYPENAME range_return::type - operator()(Policy& policy, Container& cont) - { - typedef BOOST_DEDUCED_TYPENAME range_return::type result_t; - result_t result = boost::find_first_of(cont, policy.cont(), policy.pred()); - BOOST_CHECK( result == boost::find_first_of(boost::make_iterator_range(cont), policy.cont(), policy.pred()) ); - BOOST_CHECK( result == boost::find_first_of(cont, boost::make_iterator_range(policy.cont()), policy.pred()) ); - BOOST_CHECK( result == boost::find_first_of(boost::make_iterator_range(cont), boost::make_iterator_range(policy.cont()), policy.pred()) ); - return result; - } - }; - - template - BOOST_DEDUCED_TYPENAME range_iterator::type - reference(Container& cont) - { - return std::find_first_of(cont.begin(), cont.end(), - m_cont.begin(), m_cont.end(), - m_pred); - } - - private: - Container2 m_cont; - BinaryPredicate m_pred; }; - template - void run_tests(Container1& cont1, Container2& cont2) + template + BOOST_DEDUCED_TYPENAME boost::range_iterator::type + reference(Container& cont) { - range_test::range_return_test_driver test_driver; - test_driver(cont1, find_first_of_test_policy(cont2)); - test_driver(cont1, find_first_of_pred_test_policy >(cont2)); - test_driver(cont2, find_first_of_pred_test_policy >(cont2)); + return std::find_first_of(cont.begin(), cont.end(), + m_cont.begin(), m_cont.end(), + m_pred); } - template - void test_find_first_of_impl() - { - using namespace boost::assign; + private: + Container2 m_cont; + BinaryPredicate m_pred; + }; - typedef BOOST_DEDUCED_TYPENAME remove_const::type container1_t; - typedef BOOST_DEDUCED_TYPENAME remove_const::type container2_t; + template + void run_tests(Container1& cont1, Container2& cont2) + { + boost::range_test::range_return_test_driver test_driver; + test_driver(cont1, find_first_of_test_policy(cont2)); + test_driver(cont1, find_first_of_pred_test_policy >(cont2)); + test_driver(cont2, find_first_of_pred_test_policy >(cont2)); + } - container1_t mcont1; - Container1& cont1 = mcont1; - container2_t mcont2; - Container2& cont2 = mcont2; + template + void test_find_first_of_impl() + { + using namespace boost::assign; - run_tests(cont1, cont2); + typedef BOOST_DEDUCED_TYPENAME boost::remove_const::type container1_t; + typedef BOOST_DEDUCED_TYPENAME boost::remove_const::type container2_t; - mcont1 += 1; - run_tests(cont1, cont2); + container1_t mcont1; + Container1& cont1 = mcont1; + container2_t mcont2; + Container2& cont2 = mcont2; - mcont2 += 1; - run_tests(cont1, cont2); + run_tests(cont1, cont2); - mcont1 += 2,3,4,5,6,7,8,9; - mcont2 += 2,3,4; - run_tests(cont1, cont2); + mcont1 += 1; + run_tests(cont1, cont2); - mcont2.clear(); - mcont2 += 7,8,9; - run_tests(cont1, cont2); - } + mcont2 += 1; + run_tests(cont1, cont2); - void test_find_first_of() - { - test_find_first_of_impl< std::vector, std::vector >(); - test_find_first_of_impl< std::list, std::list >(); - test_find_first_of_impl< std::deque, std::deque >(); - test_find_first_of_impl< const std::vector, const std::vector >(); - test_find_first_of_impl< const std::list, const std::list >(); - test_find_first_of_impl< const std::deque, const std::deque >(); - test_find_first_of_impl< const std::vector, const std::list >(); - test_find_first_of_impl< const std::list, const std::vector >(); - test_find_first_of_impl< const std::vector, std::list >(); - test_find_first_of_impl< const std::list, std::vector >(); - test_find_first_of_impl< std::vector, std::list >(); - test_find_first_of_impl< std::list, std::vector >(); - } + mcont1 += 2,3,4,5,6,7,8,9; + mcont2 += 2,3,4; + run_tests(cont1, cont2); + + mcont2.clear(); + mcont2 += 7,8,9; + run_tests(cont1, cont2); + } + + void test_find_first_of() + { + test_find_first_of_impl< std::vector, std::vector >(); + test_find_first_of_impl< std::list, std::list >(); + test_find_first_of_impl< std::deque, std::deque >(); + test_find_first_of_impl< const std::vector, const std::vector >(); + test_find_first_of_impl< const std::list, const std::list >(); + test_find_first_of_impl< const std::deque, const std::deque >(); + test_find_first_of_impl< const std::vector, const std::list >(); + test_find_first_of_impl< const std::list, const std::vector >(); + test_find_first_of_impl< const std::vector, std::list >(); + test_find_first_of_impl< const std::list, std::vector >(); + test_find_first_of_impl< std::vector, std::list >(); + test_find_first_of_impl< std::list, std::vector >(); } } @@ -195,7 +192,7 @@ init_unit_test_suite(int argc, char* argv[]) boost::unit_test::test_suite* test = BOOST_TEST_SUITE( "RangeTestSuite.algorithm.find_first_of" ); - test->add( BOOST_TEST_CASE( &boost::test_find_first_of ) ); + test->add( BOOST_TEST_CASE( &boost_range_test_algorithm_find_first_of::test_find_first_of ) ); return test; } diff --git a/test/algorithm_test/find_if.cpp b/test/algorithm_test/find_if.cpp index 04fe6f2..3ab22c9 100644 --- a/test/algorithm_test/find_if.cpp +++ b/test/algorithm_test/find_if.cpp @@ -23,97 +23,94 @@ #include #include -namespace boost +namespace boost_range_test_algorithm_find_if { - namespace + template + class find_if_test_policy { - template - class find_if_test_policy - { - public: - explicit find_if_test_policy(UnaryPredicate pred) - : m_pred(pred) {} - - template - BOOST_DEDUCED_TYPENAME range_iterator::type - test_iter(Container& cont) - { - typedef BOOST_DEDUCED_TYPENAME range_iterator::type iter_t; - iter_t result = boost::find_if(cont, m_pred); - BOOST_CHECK( result == boost::find_if(boost::make_iterator_range(cont), m_pred) ); - return result; - } - - template - struct test_range - { - template - BOOST_DEDUCED_TYPENAME range_return::type - operator()(find_if_test_policy& policy, Container& cont) - { - typedef BOOST_DEDUCED_TYPENAME range_return::type result_t; - result_t result = boost::find_if(cont, policy.pred()); - BOOST_CHECK( result == boost::find_if(boost::make_iterator_range(cont), policy.pred()) ); - return result; - } - }; - - template - BOOST_DEDUCED_TYPENAME range_iterator::type - reference(Container& cont) - { - return std::find_if(cont.begin(), cont.end(), m_pred); - } - - UnaryPredicate& pred() { return m_pred; } - - private: - UnaryPredicate m_pred; - }; - - template - find_if_test_policy - make_policy(UnaryPredicate pred) - { - return find_if_test_policy(pred); - } + public: + explicit find_if_test_policy(UnaryPredicate pred) + : m_pred(pred) {} template - void test_find_if_container() + BOOST_DEDUCED_TYPENAME boost::range_iterator::type + test_iter(Container& cont) { - using namespace boost::assign; - using namespace boost::range_test_function; - - typedef BOOST_DEDUCED_TYPENAME remove_const::type container_t; - - range_test::range_return_test_driver test_driver; - - container_t mcont; - Container& cont = mcont; - test_driver(cont, make_policy(greater_than_x(5))); - test_driver(cont, make_policy(false_predicate())); - - mcont.clear(); - mcont += 1; - test_driver(cont, make_policy(greater_than_x(5))); - test_driver(cont, make_policy(false_predicate())); - - mcont.clear(); - mcont += 1,2,3,4,5,6,7,8,9; - test_driver(cont, make_policy(greater_than_x(5))); - test_driver(cont, make_policy(false_predicate())); + typedef BOOST_DEDUCED_TYPENAME boost::range_iterator::type iter_t; + iter_t result = boost::find_if(cont, m_pred); + BOOST_CHECK( result == boost::find_if(boost::make_iterator_range(cont), m_pred) ); + return result; } - void test_find_if() + template + struct test_range { - test_find_if_container< std::vector >(); - test_find_if_container< std::list >(); - test_find_if_container< std::deque >(); + template + BOOST_DEDUCED_TYPENAME boost::range_return::type + operator()(find_if_test_policy& policy, Container& cont) + { + typedef BOOST_DEDUCED_TYPENAME boost::range_return::type result_t; + result_t result = boost::find_if(cont, policy.pred()); + BOOST_CHECK( result == boost::find_if(boost::make_iterator_range(cont), policy.pred()) ); + return result; + } + }; - test_find_if_container< const std::vector >(); - test_find_if_container< const std::list >(); - test_find_if_container< const std::deque >(); + template + BOOST_DEDUCED_TYPENAME boost::range_iterator::type + reference(Container& cont) + { + return std::find_if(cont.begin(), cont.end(), m_pred); } + + UnaryPredicate& pred() { return m_pred; } + + private: + UnaryPredicate m_pred; + }; + + template + find_if_test_policy + make_policy(UnaryPredicate pred) + { + return find_if_test_policy(pred); + } + + template + void test_find_if_container() + { + using namespace boost::assign; + using namespace boost::range_test_function; + + typedef BOOST_DEDUCED_TYPENAME boost::remove_const::type container_t; + + boost::range_test::range_return_test_driver test_driver; + + container_t mcont; + Container& cont = mcont; + test_driver(cont, make_policy(greater_than_x(5))); + test_driver(cont, make_policy(false_predicate())); + + mcont.clear(); + mcont += 1; + test_driver(cont, make_policy(greater_than_x(5))); + test_driver(cont, make_policy(false_predicate())); + + mcont.clear(); + mcont += 1,2,3,4,5,6,7,8,9; + test_driver(cont, make_policy(greater_than_x(5))); + test_driver(cont, make_policy(false_predicate())); + } + + void test_find_if() + { + test_find_if_container< std::vector >(); + test_find_if_container< std::list >(); + test_find_if_container< std::deque >(); + + test_find_if_container< const std::vector >(); + test_find_if_container< const std::list >(); + test_find_if_container< const std::deque >(); } } @@ -123,7 +120,7 @@ init_unit_test_suite(int argc, char* argv[]) boost::unit_test::test_suite* test = BOOST_TEST_SUITE( "RangeTestSuite.algorithm.find_if" ); - test->add( BOOST_TEST_CASE( &boost::test_find_if ) ); + test->add( BOOST_TEST_CASE( &boost_range_test_algorithm_find_if::test_find_if ) ); return test; } diff --git a/test/algorithm_test/lower_bound.cpp b/test/algorithm_test/lower_bound.cpp index e627708..2a120a4 100644 --- a/test/algorithm_test/lower_bound.cpp +++ b/test/algorithm_test/lower_bound.cpp @@ -22,164 +22,160 @@ #include #include -namespace boost +namespace boost_range_test_algorithm_lower_bound { - namespace + class lower_bound_policy { - class lower_bound_policy + public: + template< class Container > + BOOST_DEDUCED_TYPENAME boost::range_iterator::type + test_iter(Container& cont) { - public: - template< class Container > - BOOST_DEDUCED_TYPENAME range_iterator::type - test_iter(Container& cont) - { - typedef BOOST_DEDUCED_TYPENAME range_iterator::type iter_t; - iter_t result = boost::lower_bound(cont, 5); - BOOST_CHECK( result == boost::lower_bound(boost::make_iterator_range(cont), 5) ); - return result; - } - - template - struct test_range - { - template - BOOST_DEDUCED_TYPENAME range_return::type - operator()(Policy&, Container& cont) - { - typedef BOOST_DEDUCED_TYPENAME range_return::type result_t; - result_t result = boost::lower_bound(cont, 5); - BOOST_CHECK( result == boost::lower_bound(boost::make_iterator_range(cont), 5) ); - return result; - } - }; - - template< class Container > - BOOST_DEDUCED_TYPENAME range_iterator::type - reference(Container& cont) - { - return std::lower_bound(cont.begin(), cont.end(), 5); - } - }; - - template< class BinaryPredicate > - struct lower_bound_pred_policy - { - template< class Container > - BOOST_DEDUCED_TYPENAME range_iterator::type - test_iter(Container& cont) - { - typedef BOOST_DEDUCED_TYPENAME range_iterator::type iter_t; - iter_t result = boost::lower_bound(cont, 5, m_pred); - BOOST_CHECK( result == boost::lower_bound( - boost::make_iterator_range(cont), 5, m_pred) ); - return result; - } - - template< range_return_value return_type > - struct test_range - { - template - BOOST_DEDUCED_TYPENAME range_return::type - operator()(Policy& policy, Container& cont) - { - typedef BOOST_DEDUCED_TYPENAME range_return::type result_t; - result_t result = boost::lower_bound(cont, 5, policy.pred()); - BOOST_CHECK( result == boost::lower_bound( - boost::make_iterator_range(cont), 5, policy.pred()) ); - return result; - } - }; - - template - BOOST_DEDUCED_TYPENAME range_iterator::type - reference(Container& cont) - { - return std::lower_bound( - cont.begin(), cont.end(), 5, m_pred); - } - - BinaryPredicate& pred() { return m_pred; } - - private: - BinaryPredicate m_pred; - }; - - template - void test_lower_bound_impl(TestPolicy policy, BinaryPredicate pred) - { - using namespace boost::assign; - - typedef BOOST_DEDUCED_TYPENAME remove_const::type container_t; - typedef BOOST_DEDUCED_TYPENAME Container::value_type value_t; - - range_test::range_return_test_driver test_driver; - - container_t mcont; - Container& cont = mcont; - - test_driver(cont, policy); - - mcont.clear(); - mcont += 1; - - std::vector temp(mcont.begin(), mcont.end()); - std::sort(temp.begin(), temp.end(), pred); - mcont.assign(temp.begin(), temp.end()); - - test_driver(cont, policy); - - mcont.clear(); - mcont += 1,2,3,4,5,6,7,8,9; - - temp.assign(mcont.begin(), mcont.end()); - std::sort(temp.begin(), temp.end(), pred); - mcont.assign(temp.begin(), temp.end()); - - test_driver(cont, policy); + typedef BOOST_DEDUCED_TYPENAME boost::range_iterator::type iter_t; + iter_t result = boost::lower_bound(cont, 5); + BOOST_CHECK( result == boost::lower_bound(boost::make_iterator_range(cont), 5) ); + return result; } + template + struct test_range + { + template + BOOST_DEDUCED_TYPENAME boost::range_return::type + operator()(Policy&, Container& cont) + { + typedef BOOST_DEDUCED_TYPENAME boost::range_return::type result_t; + result_t result = boost::lower_bound(cont, 5); + BOOST_CHECK( result == boost::lower_bound(boost::make_iterator_range(cont), 5) ); + return result; + } + }; + + template< class Container > + BOOST_DEDUCED_TYPENAME boost::range_iterator::type + reference(Container& cont) + { + return std::lower_bound(cont.begin(), cont.end(), 5); + } + }; + + template< class BinaryPredicate > + struct lower_bound_pred_policy + { + template< class Container > + BOOST_DEDUCED_TYPENAME boost::range_iterator::type + test_iter(Container& cont) + { + typedef BOOST_DEDUCED_TYPENAME boost::range_iterator::type iter_t; + iter_t result = boost::lower_bound(cont, 5, m_pred); + BOOST_CHECK( result == boost::lower_bound( + boost::make_iterator_range(cont), 5, m_pred) ); + return result; + } + + template< boost::range_return_value return_type > + struct test_range + { + template + BOOST_DEDUCED_TYPENAME boost::range_return::type + operator()(Policy& policy, Container& cont) + { + typedef BOOST_DEDUCED_TYPENAME boost::range_return::type result_t; + result_t result = boost::lower_bound(cont, 5, policy.pred()); + BOOST_CHECK( result == boost::lower_bound( + boost::make_iterator_range(cont), 5, policy.pred()) ); + return result; + } + }; + template - void test_lower_bound_impl() + BOOST_DEDUCED_TYPENAME boost::range_iterator::type + reference(Container& cont) { - test_lower_bound_impl( - lower_bound_policy(), - std::less() - ); - - test_lower_bound_impl( - lower_bound_pred_policy >(), - std::less() - ); - - test_lower_bound_impl( - lower_bound_pred_policy >(), - std::greater() - ); + return std::lower_bound( + cont.begin(), cont.end(), 5, m_pred); } - void test_lower_bound() - { - test_lower_bound_impl< std::vector >(); - test_lower_bound_impl< std::list >(); - test_lower_bound_impl< std::deque >(); + BinaryPredicate& pred() { return m_pred; } - test_lower_bound_impl< const std::vector >(); - test_lower_bound_impl< const std::list >(); - test_lower_bound_impl< const std::deque >(); - } + private: + BinaryPredicate m_pred; + }; + + template + void test_lower_bound_impl(TestPolicy policy, BinaryPredicate pred) + { + using namespace boost::assign; + + typedef BOOST_DEDUCED_TYPENAME boost::remove_const::type container_t; + typedef BOOST_DEDUCED_TYPENAME Container::value_type value_t; + + boost::range_test::range_return_test_driver test_driver; + + container_t mcont; + Container& cont = mcont; + + test_driver(cont, policy); + + mcont.clear(); + mcont += 1; + + std::vector temp(mcont.begin(), mcont.end()); + std::sort(temp.begin(), temp.end(), pred); + mcont.assign(temp.begin(), temp.end()); + + test_driver(cont, policy); + + mcont.clear(); + mcont += 1,2,3,4,5,6,7,8,9; + + temp.assign(mcont.begin(), mcont.end()); + std::sort(temp.begin(), temp.end(), pred); + mcont.assign(temp.begin(), temp.end()); + + test_driver(cont, policy); + } + + template + void test_lower_bound_impl() + { + test_lower_bound_impl( + lower_bound_policy(), + std::less() + ); + + test_lower_bound_impl( + lower_bound_pred_policy >(), + std::less() + ); + + test_lower_bound_impl( + lower_bound_pred_policy >(), + std::greater() + ); + } + + void test_lower_bound() + { + test_lower_bound_impl< std::vector >(); + test_lower_bound_impl< std::list >(); + test_lower_bound_impl< std::deque >(); + + test_lower_bound_impl< const std::vector >(); + test_lower_bound_impl< const std::list >(); + test_lower_bound_impl< const std::deque >(); } } - boost::unit_test::test_suite* init_unit_test_suite(int argc, char* argv[]) { boost::unit_test::test_suite* test = BOOST_TEST_SUITE( "RangeTestSuite.algorithm.lower_bound" ); - test->add( BOOST_TEST_CASE( &boost::test_lower_bound ) ); + test->add( BOOST_TEST_CASE( &boost_range_test_algorithm_lower_bound::test_lower_bound ) ); return test; } diff --git a/test/algorithm_test/max_element.cpp b/test/algorithm_test/max_element.cpp index c4c6cb9..9a26099 100644 --- a/test/algorithm_test/max_element.cpp +++ b/test/algorithm_test/max_element.cpp @@ -22,134 +22,131 @@ #include #include -namespace boost +namespace boost_range_test_algorithm_max_element { - namespace + class max_element_test_policy { - class max_element_test_policy + public: + template< class Container > + BOOST_DEDUCED_TYPENAME boost::range_iterator::type + test_iter(Container& cont) { - public: - template< class Container > - BOOST_DEDUCED_TYPENAME range_iterator::type - test_iter(Container& cont) + typedef BOOST_DEDUCED_TYPENAME boost::range_iterator::type iter_t; + iter_t result = boost::max_element(cont); + BOOST_CHECK( result == boost::max_element( + boost::make_iterator_range(cont)) ); + return result; + } + + template + struct test_range + { + template + BOOST_DEDUCED_TYPENAME boost::range_return::type + operator()(Policy&, Container& cont) { - typedef BOOST_DEDUCED_TYPENAME range_iterator::type iter_t; - iter_t result = boost::max_element(cont); - BOOST_CHECK( result == boost::max_element( + typedef BOOST_DEDUCED_TYPENAME boost::range_return::type result_t; + result_t result = boost::max_element(cont); + BOOST_CHECK( result == boost::max_element( boost::make_iterator_range(cont)) ); return result; } - - template - struct test_range - { - template - BOOST_DEDUCED_TYPENAME range_return::type - operator()(Policy&, Container& cont) - { - typedef BOOST_DEDUCED_TYPENAME range_return::type result_t; - result_t result = boost::max_element(cont); - BOOST_CHECK( result == boost::max_element( - boost::make_iterator_range(cont)) ); - return result; - } - }; - - template< class Container > - BOOST_DEDUCED_TYPENAME range_iterator::type - reference(Container& cont) - { - return std::max_element(cont.begin(), cont.end()); - } }; - template - class max_element_pred_test_policy + template< class Container > + BOOST_DEDUCED_TYPENAME boost::range_iterator::type + reference(Container& cont) { - public: - template< class Container > - BOOST_DEDUCED_TYPENAME range_iterator::type - test_iter(Container& cont) + return std::max_element(cont.begin(), cont.end()); + } + }; + + template + class max_element_pred_test_policy + { + public: + template< class Container > + BOOST_DEDUCED_TYPENAME boost::range_iterator::type + test_iter(Container& cont) + { + typedef BOOST_DEDUCED_TYPENAME boost::range_iterator::type iter_t; + iter_t result = boost::max_element(cont, Pred()); + BOOST_CHECK( result == boost::max_element( + boost::make_iterator_range(cont), Pred()) ); + return result; + } + + Pred pred() const { return Pred(); } + + template< boost::range_return_value return_type > + struct test_range + { + template< class Container, class Policy > + BOOST_DEDUCED_TYPENAME boost::range_return::type + operator()(Policy& policy, Container& cont) { - typedef BOOST_DEDUCED_TYPENAME range_iterator::type iter_t; - iter_t result = boost::max_element(cont, Pred()); - BOOST_CHECK( result == boost::max_element( - boost::make_iterator_range(cont), Pred()) ); + typedef BOOST_DEDUCED_TYPENAME boost::range_return::type result_t; + result_t result = boost::max_element(cont, policy.pred()); + BOOST_CHECK( result == boost::max_element( + boost::make_iterator_range(cont), policy.pred()) ); return result; } - - Pred pred() const { return Pred(); } - - template< range_return_value return_type > - struct test_range - { - template< class Container, class Policy > - BOOST_DEDUCED_TYPENAME range_return::type - operator()(Policy& policy, Container& cont) - { - typedef BOOST_DEDUCED_TYPENAME range_return::type result_t; - result_t result = boost::max_element(cont, policy.pred()); - BOOST_CHECK( result == boost::max_element( - boost::make_iterator_range(cont), policy.pred()) ); - return result; - } - }; - - template< class Container > - BOOST_DEDUCED_TYPENAME range_iterator::type - reference(Container& cont) - { - return std::max_element(cont.begin(), cont.end(), Pred()); - } }; - template - void test_max_element_impl(TestPolicy policy) + template< class Container > + BOOST_DEDUCED_TYPENAME boost::range_iterator::type + reference(Container& cont) { - using namespace boost::assign; - - typedef BOOST_DEDUCED_TYPENAME Container::value_type value_t; - typedef BOOST_DEDUCED_TYPENAME remove_const::type container_t; - - range_test::range_return_test_driver test_driver; - - container_t cont; - - test_driver(cont, policy); - - cont.clear(); - cont += 1; - - test_driver(cont, policy); - - cont.clear(); - cont += 1,2,2,2,3,4,5,6,7,8,9; - - test_driver(cont, policy); + return std::max_element(cont.begin(), cont.end(), Pred()); } + }; - template - void test_max_element_impl() - { - test_max_element_impl(max_element_test_policy()); - - test_max_element_impl( - max_element_pred_test_policy >()); + template + void test_max_element_impl(TestPolicy policy) + { + using namespace boost::assign; - test_max_element_impl( - max_element_pred_test_policy >()); - } + typedef BOOST_DEDUCED_TYPENAME Container::value_type value_t; + typedef BOOST_DEDUCED_TYPENAME boost::remove_const::type container_t; - void test_max_element() - { - test_max_element_impl< const std::vector >(); - test_max_element_impl< const std::deque >(); - test_max_element_impl< const std::list >(); + boost::range_test::range_return_test_driver test_driver; - test_max_element_impl< std::vector >(); - test_max_element_impl< std::deque >(); - test_max_element_impl< std::list >(); - } + container_t cont; + + test_driver(cont, policy); + + cont.clear(); + cont += 1; + + test_driver(cont, policy); + + cont.clear(); + cont += 1,2,2,2,3,4,5,6,7,8,9; + + test_driver(cont, policy); + } + + template + void test_max_element_impl() + { + test_max_element_impl(max_element_test_policy()); + + test_max_element_impl( + max_element_pred_test_policy >()); + + test_max_element_impl( + max_element_pred_test_policy >()); + } + + void test_max_element() + { + test_max_element_impl< const std::vector >(); + test_max_element_impl< const std::deque >(); + test_max_element_impl< const std::list >(); + + test_max_element_impl< std::vector >(); + test_max_element_impl< std::deque >(); + test_max_element_impl< std::list >(); } } @@ -159,7 +156,7 @@ init_unit_test_suite(int argc, char* argv[]) boost::unit_test::test_suite* test = BOOST_TEST_SUITE( "RangeTestSuite.algorithm.max_element" ); - test->add( BOOST_TEST_CASE( &boost::test_max_element ) ); + test->add( BOOST_TEST_CASE( &boost_range_test_algorithm_max_element::test_max_element ) ); return test; } diff --git a/test/algorithm_test/min_element.cpp b/test/algorithm_test/min_element.cpp index c8fceda..0f9fa68 100644 --- a/test/algorithm_test/min_element.cpp +++ b/test/algorithm_test/min_element.cpp @@ -22,132 +22,129 @@ #include #include -namespace boost +namespace boost_range_test_algorithm_min_element { - namespace + class min_element_test_policy { - class min_element_test_policy + public: + template< class Container > + BOOST_DEDUCED_TYPENAME boost::range_iterator::type + test_iter(Container& cont) { - public: - template< class Container > - BOOST_DEDUCED_TYPENAME range_iterator::type - test_iter(Container& cont) + typedef BOOST_DEDUCED_TYPENAME boost::range_iterator::type iter_t; + iter_t result = boost::min_element(cont); + BOOST_CHECK( result == boost::min_element(boost::make_iterator_range(cont)) ); + return result; + } + + template< boost::range_return_value return_type > + struct test_range + { + template< class Container, class Policy > + BOOST_DEDUCED_TYPENAME boost::range_return::type + operator()(Policy&, Container& cont) { - typedef BOOST_DEDUCED_TYPENAME range_iterator::type iter_t; - iter_t result = boost::min_element(cont); - BOOST_CHECK( result == boost::min_element(boost::make_iterator_range(cont)) ); + typedef BOOST_DEDUCED_TYPENAME boost::range_return::type result_t; + result_t result = boost::min_element(cont); + BOOST_CHECK( result == boost::min_element(boost::make_iterator_range(cont)) ); return result; } - - template< range_return_value return_type > - struct test_range - { - template< class Container, class Policy > - BOOST_DEDUCED_TYPENAME range_return::type - operator()(Policy&, Container& cont) - { - typedef BOOST_DEDUCED_TYPENAME range_return::type result_t; - result_t result = boost::min_element(cont); - BOOST_CHECK( result == boost::min_element(boost::make_iterator_range(cont)) ); - return result; - } - }; - - template< class Container > - BOOST_DEDUCED_TYPENAME range_iterator::type - reference(Container& cont) - { - return std::min_element(cont.begin(), cont.end()); - } }; - template - class min_element_pred_test_policy + template< class Container > + BOOST_DEDUCED_TYPENAME boost::range_iterator::type + reference(Container& cont) { - public: - template< class Container > - BOOST_DEDUCED_TYPENAME range_iterator::type - test_iter(Container& cont) + return std::min_element(cont.begin(), cont.end()); + } + }; + + template + class min_element_pred_test_policy + { + public: + template< class Container > + BOOST_DEDUCED_TYPENAME boost::range_iterator::type + test_iter(Container& cont) + { + typedef BOOST_DEDUCED_TYPENAME boost::range_iterator::type iter_t; + iter_t result = boost::min_element(cont, Pred()); + BOOST_CHECK( result == boost::min_element( + boost::make_iterator_range(cont), Pred()) ); + return result; + } + + Pred pred() const { return Pred(); } + + template< boost::range_return_value return_type > + struct test_range + { + template< class Container, class Policy > + BOOST_DEDUCED_TYPENAME boost::range_return::type + operator()(Policy& policy, Container& cont) { - typedef BOOST_DEDUCED_TYPENAME range_iterator::type iter_t; - iter_t result = boost::min_element(cont, Pred()); - BOOST_CHECK( result == boost::min_element( - boost::make_iterator_range(cont), Pred()) ); + typedef BOOST_DEDUCED_TYPENAME boost::range_return::type result_t; + result_t result = boost::min_element(cont, policy.pred()); + BOOST_CHECK( result == boost::min_element( + boost::make_iterator_range(cont), policy.pred()) ); return result; } - - Pred pred() const { return Pred(); } - - template< range_return_value return_type > - struct test_range - { - template< class Container, class Policy > - BOOST_DEDUCED_TYPENAME range_return::type - operator()(Policy& policy, Container& cont) - { - typedef BOOST_DEDUCED_TYPENAME range_return::type result_t; - result_t result = boost::min_element(cont, policy.pred()); - BOOST_CHECK( result == boost::min_element( - boost::make_iterator_range(cont), policy.pred()) ); - return result; - } - }; - - template< class Container > - BOOST_DEDUCED_TYPENAME range_iterator::type - reference(Container& cont) - { - return std::min_element(cont.begin(), cont.end(), Pred()); - } }; - template - void test_min_element_impl(TestPolicy policy) + template< class Container > + BOOST_DEDUCED_TYPENAME boost::range_iterator::type + reference(Container& cont) { - using namespace boost::assign; - - typedef BOOST_DEDUCED_TYPENAME Container::value_type value_t; - typedef BOOST_DEDUCED_TYPENAME remove_const::type container_t; - - range_test::range_return_test_driver test_driver; - - container_t cont; - - test_driver(cont, policy); - - cont.clear(); - cont += 1; - - test_driver(cont, policy); - - cont.clear(); - cont += 1,2,2,2,3,4,5,6,7,8,9; - - test_driver(cont, policy); + return std::min_element(cont.begin(), cont.end(), Pred()); } + }; - template - void test_min_element_impl() - { - test_min_element_impl(min_element_test_policy()); - - test_min_element_impl( - min_element_pred_test_policy >()); + template + void test_min_element_impl(TestPolicy policy) + { + using namespace boost::assign; - test_min_element_impl( - min_element_pred_test_policy >()); - } + typedef BOOST_DEDUCED_TYPENAME Container::value_type value_t; + typedef BOOST_DEDUCED_TYPENAME boost::remove_const::type container_t; - void test_min_element() - { - test_min_element_impl< const std::vector >(); - test_min_element_impl< const std::deque >(); - test_min_element_impl< const std::list >(); + boost::range_test::range_return_test_driver test_driver; - test_min_element_impl< std::vector >(); - test_min_element_impl< std::deque >(); - test_min_element_impl< std::list >(); - } + container_t cont; + + test_driver(cont, policy); + + cont.clear(); + cont += 1; + + test_driver(cont, policy); + + cont.clear(); + cont += 1,2,2,2,3,4,5,6,7,8,9; + + test_driver(cont, policy); + } + + template + void test_min_element_impl() + { + test_min_element_impl(min_element_test_policy()); + + test_min_element_impl( + min_element_pred_test_policy >()); + + test_min_element_impl( + min_element_pred_test_policy >()); + } + + void test_min_element() + { + test_min_element_impl< const std::vector >(); + test_min_element_impl< const std::deque >(); + test_min_element_impl< const std::list >(); + + test_min_element_impl< std::vector >(); + test_min_element_impl< std::deque >(); + test_min_element_impl< std::list >(); } } @@ -157,7 +154,7 @@ init_unit_test_suite(int argc, char* argv[]) boost::unit_test::test_suite* test = BOOST_TEST_SUITE( "RangeTestSuite.algorithm.min_element" ); - test->add( BOOST_TEST_CASE( &boost::test_min_element ) ); + test->add( BOOST_TEST_CASE( &boost_range_test_algorithm_min_element::test_min_element ) ); return test; } diff --git a/test/algorithm_test/partition.cpp b/test/algorithm_test/partition.cpp index 0160dae..22aefd6 100644 --- a/test/algorithm_test/partition.cpp +++ b/test/algorithm_test/partition.cpp @@ -21,109 +21,106 @@ #include #include -namespace boost +namespace boost_range_test_algorithm_partition { - namespace + struct equal_to_5 { - struct equal_to_5 - { - typedef bool result_type; - typedef int argument_type; - bool operator()(int x) const { return x == 5; } - }; + typedef bool result_type; + typedef int argument_type; + bool operator()(int x) const { return x == 5; } + }; - // test the 'partition' algorithm - template - class partition_test_policy + // test the 'partition' algorithm + template + class partition_test_policy + { + public: + template< class Container > + BOOST_DEDUCED_TYPENAME boost::range_iterator::type + test_iter(Container& cont) { - public: - template< class Container > - BOOST_DEDUCED_TYPENAME range_iterator::type - test_iter(Container& cont) + typedef BOOST_DEDUCED_TYPENAME boost::range_iterator::type iter_t; + + const Container old_cont(cont); + Container cont2(old_cont); + iter_t result = boost::partition(cont, UnaryPredicate()); + + boost::partition(cont2, UnaryPredicate()); + cont2 = old_cont; + boost::partition( + boost::make_iterator_range(cont2), UnaryPredicate()); + + BOOST_CHECK_EQUAL_COLLECTIONS( cont.begin(), cont.end(), + cont2.begin(), cont2.end() ); + + return result; + } + + UnaryPredicate pred() const { return UnaryPredicate(); } + + template< boost::range_return_value return_type > + struct test_range + { + template< class Container, class Policy > + BOOST_DEDUCED_TYPENAME boost::range_return::type + operator()(Policy& policy, Container& cont) { - typedef BOOST_DEDUCED_TYPENAME range_iterator::type iter_t; + typedef BOOST_DEDUCED_TYPENAME boost::range_return::type result_t; const Container old_cont(cont); Container cont2(old_cont); - iter_t result = boost::partition(cont, UnaryPredicate()); + result_t result = boost::partition(cont, policy.pred()); - boost::partition(cont2, UnaryPredicate()); - cont2 = old_cont; - boost::partition( - boost::make_iterator_range(cont2), UnaryPredicate()); + // Test that operation a temporary created by using + // make_iterator_range. + boost::partition( + boost::make_iterator_range(cont2), policy.pred()); BOOST_CHECK_EQUAL_COLLECTIONS( cont.begin(), cont.end(), cont2.begin(), cont2.end() ); return result; } - - UnaryPredicate pred() const { return UnaryPredicate(); } - - template< range_return_value return_type > - struct test_range - { - template< class Container, class Policy > - BOOST_DEDUCED_TYPENAME range_return::type - operator()(Policy& policy, Container& cont) - { - typedef BOOST_DEDUCED_TYPENAME range_return::type result_t; - - const Container old_cont(cont); - Container cont2(old_cont); - result_t result = boost::partition(cont, policy.pred()); - - // Test that operation a temporary created by using - // make_iterator_range. - boost::partition( - boost::make_iterator_range(cont2), policy.pred()); - - BOOST_CHECK_EQUAL_COLLECTIONS( cont.begin(), cont.end(), - cont2.begin(), cont2.end() ); - - return result; - } - }; - - template< class Container > - BOOST_DEDUCED_TYPENAME range_iterator::type - reference(Container& cont) - { - return std::partition(cont.begin(), cont.end(), UnaryPredicate()); - } }; - template - void test_partition_impl() + template< class Container > + BOOST_DEDUCED_TYPENAME boost::range_iterator::type + reference(Container& cont) { - using namespace boost::assign; - - range_test::range_return_test_driver test_driver; - - partition_test_policy< equal_to_5 > policy; - - Container cont; - test_driver(cont, policy); - - cont.clear(); - cont += 1; - test_driver(cont, policy); - - cont.clear(); - cont += 1,2,2,2,2,2,3,4,5,6,7,8,9; - test_driver(cont, policy); - - cont.clear(); - cont += 1,2,2,2,2,2,3,3,3,3,4,4,4,4,4,4,4,5,6,7,8,9; - test_driver(cont, policy); + return std::partition(cont.begin(), cont.end(), UnaryPredicate()); } + }; - void test_partition() - { - test_partition_impl< std::vector >(); - test_partition_impl< std::list >(); - test_partition_impl< std::deque >(); - } + template + void test_partition_impl() + { + using namespace boost::assign; + + boost::range_test::range_return_test_driver test_driver; + + partition_test_policy< equal_to_5 > policy; + + Container cont; + test_driver(cont, policy); + + cont.clear(); + cont += 1; + test_driver(cont, policy); + + cont.clear(); + cont += 1,2,2,2,2,2,3,4,5,6,7,8,9; + test_driver(cont, policy); + + cont.clear(); + cont += 1,2,2,2,2,2,3,3,3,3,4,4,4,4,4,4,4,5,6,7,8,9; + test_driver(cont, policy); + } + + void test_partition() + { + test_partition_impl< std::vector >(); + test_partition_impl< std::list >(); + test_partition_impl< std::deque >(); } } @@ -133,7 +130,7 @@ init_unit_test_suite(int argc, char* argv[]) boost::unit_test::test_suite* test = BOOST_TEST_SUITE( "RangeTestSuite.algorithm.partition" ); - test->add( BOOST_TEST_CASE( &boost::test_partition ) ); + test->add( BOOST_TEST_CASE( &boost_range_test_algorithm_partition::test_partition ) ); return test; } diff --git a/test/algorithm_test/stable_partition.cpp b/test/algorithm_test/stable_partition.cpp index 5f55b7d..3bf20e2 100644 --- a/test/algorithm_test/stable_partition.cpp +++ b/test/algorithm_test/stable_partition.cpp @@ -21,116 +21,112 @@ #include #include -namespace boost +namespace boost_range_test_algorithm_stable_partition { - namespace + struct equal_to_5 { - struct equal_to_5 - { - typedef bool result_type; - typedef int argument_type; - bool operator()(int x) const { return x == 5; } - }; + typedef bool result_type; + typedef int argument_type; + bool operator()(int x) const { return x == 5; } + }; - // test the 'partition' algorithm - template - class stable_partition_test_policy + // test the 'partition' algorithm + template + class stable_partition_test_policy + { + public: + template< class Container > + BOOST_DEDUCED_TYPENAME boost::range_iterator::type + test_iter(Container& cont) { - public: - template< class Container > - BOOST_DEDUCED_TYPENAME range_iterator::type - test_iter(Container& cont) + Container cont2(cont); + + typedef BOOST_DEDUCED_TYPENAME boost::range_iterator::type iter_t; + iter_t result = boost::stable_partition(cont, UnaryPredicate()); + + iter_t temp_result = boost::stable_partition( + boost::make_iterator_range(cont2), UnaryPredicate()); + + BOOST_CHECK_EQUAL( std::distance(cont.begin(), result), + std::distance(cont2.begin(), temp_result) ); + + BOOST_CHECK_EQUAL_COLLECTIONS( cont.begin(), cont.end(), + cont2.begin(), cont2.end() ); + + return result; + } + + UnaryPredicate pred() const { return UnaryPredicate(); } + + template< boost::range_return_value return_type > + struct test_range + { + template< class Container, class Policy > + BOOST_DEDUCED_TYPENAME boost::range_return::type + operator()(Policy& policy, Container& cont) { + typedef BOOST_DEDUCED_TYPENAME boost::range_return::type result_t; Container cont2(cont); - - typedef BOOST_DEDUCED_TYPENAME range_iterator::type iter_t; - iter_t result = boost::stable_partition(cont, UnaryPredicate()); - - iter_t temp_result = boost::stable_partition( - boost::make_iterator_range(cont2), UnaryPredicate()); - - BOOST_CHECK_EQUAL( std::distance(cont.begin(), result), - std::distance(cont2.begin(), temp_result) ); - - BOOST_CHECK_EQUAL_COLLECTIONS( cont.begin(), cont.end(), - cont2.begin(), cont2.end() ); - + result_t result = boost::stable_partition(cont, policy.pred()); + + result_t result2 = boost::stable_partition( + boost::make_iterator_range(cont2), policy.pred()); + + BOOST_CHECK_EQUAL_COLLECTIONS( cont2.begin(), cont2.end(), + cont.begin(), cont.end() ); + return result; } - - UnaryPredicate pred() const { return UnaryPredicate(); } - - template< range_return_value return_type > - struct test_range - { - template< class Container, class Policy > - BOOST_DEDUCED_TYPENAME range_return::type - operator()(Policy& policy, Container& cont) - { - typedef BOOST_DEDUCED_TYPENAME range_return::type result_t; - Container cont2(cont); - result_t result = boost::stable_partition(cont, policy.pred()); - - result_t result2 = boost::stable_partition( - boost::make_iterator_range(cont2), policy.pred()); - - BOOST_CHECK_EQUAL_COLLECTIONS( cont2.begin(), cont2.end(), - cont.begin(), cont.end() ); - - return result; - } - }; - - template< class Container > - BOOST_DEDUCED_TYPENAME range_iterator::type - reference(Container& cont) - { - return std::stable_partition(cont.begin(), cont.end(), UnaryPredicate()); - } }; - template - void test_stable_partition_impl() + template< class Container > + BOOST_DEDUCED_TYPENAME boost::range_iterator::type + reference(Container& cont) { - using namespace boost::assign; - - range_test::range_return_test_driver test_driver; - - stable_partition_test_policy< equal_to_5 > policy; - - Container cont; - test_driver(cont, policy); - - cont.clear(); - cont += 1; - test_driver(cont, policy); - - cont.clear(); - cont += 1,2,2,2,2,2,3,4,5,6,7,8,9; - test_driver(cont, policy); - - cont.clear(); - cont += 1,2,2,2,2,2,3,3,3,3,4,4,4,4,4,4,4,5,6,7,8,9; - test_driver(cont, policy); + return std::stable_partition(cont.begin(), cont.end(), UnaryPredicate()); } + }; - void test_stable_partition() - { - test_stable_partition_impl< std::vector >(); - test_stable_partition_impl< std::list >(); - test_stable_partition_impl< std::deque >(); - } + template + void test_stable_partition_impl() + { + using namespace boost::assign; + + boost::range_test::range_return_test_driver test_driver; + + stable_partition_test_policy< equal_to_5 > policy; + + Container cont; + test_driver(cont, policy); + + cont.clear(); + cont += 1; + test_driver(cont, policy); + + cont.clear(); + cont += 1,2,2,2,2,2,3,4,5,6,7,8,9; + test_driver(cont, policy); + + cont.clear(); + cont += 1,2,2,2,2,2,3,3,3,3,4,4,4,4,4,4,4,5,6,7,8,9; + test_driver(cont, policy); + } + + void test_stable_partition() + { + test_stable_partition_impl< std::vector >(); + test_stable_partition_impl< std::list >(); + test_stable_partition_impl< std::deque >(); } } - boost::unit_test::test_suite* init_unit_test_suite(int argc, char* argv[]) { boost::unit_test::test_suite* test = BOOST_TEST_SUITE( "RangeTestSuite.algorithm.stable_partition" ); - test->add( BOOST_TEST_CASE( &boost::test_stable_partition ) ); + test->add( BOOST_TEST_CASE( &boost_range_test_algorithm_stable_partition::test_stable_partition ) ); return test; } diff --git a/test/algorithm_test/unique.cpp b/test/algorithm_test/unique.cpp index 49af0e3..880c131 100644 --- a/test/algorithm_test/unique.cpp +++ b/test/algorithm_test/unique.cpp @@ -23,156 +23,153 @@ #include #include -namespace boost +namespace boost_range_test_algorithm_unique { - namespace + // test the 'unique' algorithm without a predicate + class unique_test_policy { - // test the 'unique' algorithm without a predicate - class unique_test_policy + public: + template< class Container > + BOOST_DEDUCED_TYPENAME boost::range_iterator::type + test_iter(Container& cont) { - public: - template< class Container > - BOOST_DEDUCED_TYPENAME range_iterator::type - test_iter(Container& cont) - { - // There isn't an iterator return version of boost::unique, so just - // perform the standard algorithm - return std::unique(cont.begin(), cont.end()); - } + // There isn't an iterator return version of boost::unique, so just + // perform the standard algorithm + return std::unique(cont.begin(), cont.end()); + } - template< range_return_value return_type > - struct test_range + template< boost::range_return_value return_type > + struct test_range + { + template< class Container, class Policy > + BOOST_DEDUCED_TYPENAME boost::range_return::type + operator()(Policy&, Container& cont) { - template< class Container, class Policy > - BOOST_DEDUCED_TYPENAME range_return::type - operator()(Policy&, Container& cont) - { - typedef BOOST_DEDUCED_TYPENAME range_return::type result_t; - - Container cont2(cont); - - result_t result = boost::unique(cont); - - boost::unique(boost::make_iterator_range(cont2)); - - BOOST_CHECK_EQUAL_COLLECTIONS( cont.begin(), cont.end(), - cont2.begin(), cont2.end() ); - - return result; - } - }; + typedef BOOST_DEDUCED_TYPENAME boost::range_return::type result_t; - template< class Container > - BOOST_DEDUCED_TYPENAME range_iterator::type - reference(Container& cont) - { - return std::unique(cont.begin(), cont.end()); + Container cont2(cont); + + result_t result = boost::unique(cont); + + boost::unique(boost::make_iterator_range(cont2)); + + BOOST_CHECK_EQUAL_COLLECTIONS( cont.begin(), cont.end(), + cont2.begin(), cont2.end() ); + + return result; } }; - // test the 'unique' algorithm with a predicate - template - class unique_pred_test_policy + template< class Container > + BOOST_DEDUCED_TYPENAME boost::range_iterator::type + reference(Container& cont) { - public: - template< class Container > - BOOST_DEDUCED_TYPENAME range_iterator::type - test_iter(Container& cont) - { - // There isn't an iterator return version of boost::unique, so just - // perform the standard algorithm - return std::unique(cont.begin(), cont.end(), Pred()); - } + return std::unique(cont.begin(), cont.end()); + } + }; - Pred pred() const { return Pred(); } + // test the 'unique' algorithm with a predicate + template + class unique_pred_test_policy + { + public: + template< class Container > + BOOST_DEDUCED_TYPENAME boost::range_iterator::type + test_iter(Container& cont) + { + // There isn't an iterator return version of boost::unique, so just + // perform the standard algorithm + return std::unique(cont.begin(), cont.end(), Pred()); + } - template< range_return_value return_type > - struct test_range - { - template< class Container, class Policy > - BOOST_DEDUCED_TYPENAME range_return::type - operator()(Policy& policy, Container& cont) - { - typedef BOOST_DEDUCED_TYPENAME range_return::type result_t; - - Container cont2(cont); - - result_t result = boost::unique(cont, policy.pred()); - - boost::unique(boost::make_iterator_range(cont2), policy.pred()); - - BOOST_CHECK_EQUAL_COLLECTIONS( cont.begin(), cont.end(), - cont2.begin(), cont2.end() ); - - return result; - } - }; + Pred pred() const { return Pred(); } - template< class Container > - BOOST_DEDUCED_TYPENAME range_iterator::type - reference(Container& cont) + template< boost::range_return_value return_type > + struct test_range + { + template< class Container, class Policy > + BOOST_DEDUCED_TYPENAME boost::range_return::type + operator()(Policy& policy, Container& cont) { - return std::unique(cont.begin(), cont.end(), Pred()); + typedef BOOST_DEDUCED_TYPENAME boost::range_return::type result_t; + + Container cont2(cont); + + result_t result = boost::unique(cont, policy.pred()); + + boost::unique(boost::make_iterator_range(cont2), policy.pred()); + + BOOST_CHECK_EQUAL_COLLECTIONS( cont.begin(), cont.end(), + cont2.begin(), cont2.end() ); + + return result; } }; - template - void test_unique_impl(TestPolicy policy, Pred pred) + template< class Container > + BOOST_DEDUCED_TYPENAME boost::range_iterator::type + reference(Container& cont) { - using namespace boost::assign; - - typedef BOOST_DEDUCED_TYPENAME Container::value_type value_t; - - range_test::range_return_test_driver test_driver; - - Container cont; - - test_driver(cont, policy); - - cont.clear(); - cont += 1; - - std::vector temp(cont.begin(), cont.end()); - std::sort(temp.begin(), temp.end(), pred); - cont.assign(temp.begin(), temp.end()); - - test_driver(cont, policy); - - cont.clear(); - cont += 1,2,2,2,2,3,4,5,6,7,8,9; - - temp.assign(cont.begin(), cont.end()); - std::sort(temp.begin(), temp.end(), pred); - cont.assign(temp.begin(), temp.end()); - - test_driver(cont, policy); + return std::unique(cont.begin(), cont.end(), Pred()); } + }; - template - void test_unique_impl() - { - test_unique_impl( - unique_test_policy(), - std::less() - ); + template + void test_unique_impl(TestPolicy policy, Pred pred) + { + using namespace boost::assign; - test_unique_impl( - unique_pred_test_policy >(), - std::less() - ); - - test_unique_impl( - unique_pred_test_policy >(), - std::greater() - ); - } + typedef BOOST_DEDUCED_TYPENAME Container::value_type value_t; - void test_unique() - { - test_unique_impl< std::vector >(); - test_unique_impl< std::list >(); - test_unique_impl< std::deque >(); - } + boost::range_test::range_return_test_driver test_driver; + + Container cont; + + test_driver(cont, policy); + + cont.clear(); + cont += 1; + + std::vector temp(cont.begin(), cont.end()); + std::sort(temp.begin(), temp.end(), pred); + cont.assign(temp.begin(), temp.end()); + + test_driver(cont, policy); + + cont.clear(); + cont += 1,2,2,2,2,3,4,5,6,7,8,9; + + temp.assign(cont.begin(), cont.end()); + std::sort(temp.begin(), temp.end(), pred); + cont.assign(temp.begin(), temp.end()); + + test_driver(cont, policy); + } + + template + void test_unique_impl() + { + test_unique_impl( + unique_test_policy(), + std::less() + ); + + test_unique_impl( + unique_pred_test_policy >(), + std::less() + ); + + test_unique_impl( + unique_pred_test_policy >(), + std::greater() + ); + } + + void test_unique() + { + test_unique_impl< std::vector >(); + test_unique_impl< std::list >(); + test_unique_impl< std::deque >(); } } @@ -182,7 +179,7 @@ init_unit_test_suite(int argc, char* argv[]) boost::unit_test::test_suite* test = BOOST_TEST_SUITE( "RangeTestSuite.algorithm.unique" ); - test->add( BOOST_TEST_CASE( &boost::test_unique ) ); + test->add( BOOST_TEST_CASE( &boost_range_test_algorithm_unique::test_unique ) ); return test; } diff --git a/test/algorithm_test/upper_bound.cpp b/test/algorithm_test/upper_bound.cpp index 95e3965..daae764 100644 --- a/test/algorithm_test/upper_bound.cpp +++ b/test/algorithm_test/upper_bound.cpp @@ -21,144 +21,141 @@ #include #include -namespace boost +namespace boost_range_test_algorithm_upper_bound { - namespace + class upper_bound_policy { - class upper_bound_policy + public: + template< class Container > + BOOST_DEDUCED_TYPENAME boost::range_iterator::type + test_iter(Container& cont) { - public: - template< class Container > - BOOST_DEDUCED_TYPENAME range_iterator::type - test_iter(Container& cont) - { - typedef BOOST_DEDUCED_TYPENAME range_iterator::type iter_t; - iter_t result = boost::upper_bound(cont, 5); - BOOST_CHECK( result == boost::upper_bound(boost::make_iterator_range(cont), 5) ); - return result; - } - - template - struct test_range - { - template - BOOST_DEDUCED_TYPENAME range_return::type - operator()(Policy&, Container& cont) - { - typedef BOOST_DEDUCED_TYPENAME range_return::type result_t; - result_t result = boost::upper_bound(cont, 5); - BOOST_CHECK( result == boost::upper_bound(boost::make_iterator_range(cont), 5) ); - return result; - } - }; - - template< class Container > - BOOST_DEDUCED_TYPENAME range_iterator::type - reference(Container& cont) - { - return std::upper_bound(cont.begin(), cont.end(), 5); - } - }; - - template< class BinaryPredicate > - struct upper_bound_pred_policy - { - template< class Container > - BOOST_DEDUCED_TYPENAME range_iterator::type - test_iter(Container& cont) - { - typedef BOOST_DEDUCED_TYPENAME range_iterator::type iter_t; - iter_t result = boost::upper_bound(cont, 5, BinaryPredicate()); - BOOST_CHECK( result == boost::upper_bound(boost::make_iterator_range(cont), 5, BinaryPredicate()) ); - return result; - } - - template< range_return_value result_type> - struct test_range - { - template< class Container, class Policy > - BOOST_DEDUCED_TYPENAME range_return::type - operator()(Policy& policy, Container& cont) - { - typedef BOOST_DEDUCED_TYPENAME range_return::type result_t; - - result_t result = boost::upper_bound(cont, 5, policy.pred()); - - BOOST_CHECK( result == boost::upper_bound( - boost::make_iterator_range(cont), 5, policy.pred()) ); - - return result; - } - }; - - template - BOOST_DEDUCED_TYPENAME range_iterator::type - reference(Container& cont) - { - return std::upper_bound( - cont.begin(), cont.end(), 5, BinaryPredicate()); - } - - BinaryPredicate& pred() { return m_pred; } - - private: - BinaryPredicate m_pred; - }; - - template - void test_upper_bound_impl(TestPolicy policy, BinaryPredicate pred) - { - using namespace boost::assign; - - typedef BOOST_DEDUCED_TYPENAME remove_const::type container_t; - typedef BOOST_DEDUCED_TYPENAME Container::value_type value_t; - - range_test::range_return_test_driver test_driver; - - container_t mcont; - Container& cont = mcont; - - test_driver(cont, policy); - - mcont.clear(); - mcont += 1; - - std::vector temp(mcont.begin(), mcont.end()); - std::sort(temp.begin(), temp.end(), pred); - mcont.assign(temp.begin(), temp.end()); - - test_driver(cont, policy); - - mcont.clear(); - mcont += 1,2,3,4,5,6,7,8,9; - - temp.assign(mcont.begin(), mcont.end()); - std::sort(temp.begin(), temp.end(), pred); - mcont.assign(temp.begin(), temp.end()); - - test_driver(cont, policy); + typedef BOOST_DEDUCED_TYPENAME boost::range_iterator::type iter_t; + iter_t result = boost::upper_bound(cont, 5); + BOOST_CHECK( result == boost::upper_bound(boost::make_iterator_range(cont), 5) ); + return result; } + template + struct test_range + { + template + BOOST_DEDUCED_TYPENAME boost::range_return::type + operator()(Policy&, Container& cont) + { + typedef BOOST_DEDUCED_TYPENAME boost::range_return::type result_t; + result_t result = boost::upper_bound(cont, 5); + BOOST_CHECK( result == boost::upper_bound(boost::make_iterator_range(cont), 5) ); + return result; + } + }; + + template< class Container > + BOOST_DEDUCED_TYPENAME boost::range_iterator::type + reference(Container& cont) + { + return std::upper_bound(cont.begin(), cont.end(), 5); + } + }; + + template< class BinaryPredicate > + struct upper_bound_pred_policy + { + template< class Container > + BOOST_DEDUCED_TYPENAME boost::range_iterator::type + test_iter(Container& cont) + { + typedef BOOST_DEDUCED_TYPENAME boost::range_iterator::type iter_t; + iter_t result = boost::upper_bound(cont, 5, BinaryPredicate()); + BOOST_CHECK( result == boost::upper_bound(boost::make_iterator_range(cont), 5, BinaryPredicate()) ); + return result; + } + + template< boost::range_return_value result_type> + struct test_range + { + template< class Container, class Policy > + BOOST_DEDUCED_TYPENAME boost::range_return::type + operator()(Policy& policy, Container& cont) + { + typedef BOOST_DEDUCED_TYPENAME boost::range_return::type result_t; + + result_t result = boost::upper_bound(cont, 5, policy.pred()); + + BOOST_CHECK( result == boost::upper_bound( + boost::make_iterator_range(cont), 5, policy.pred()) ); + + return result; + } + }; + template - void test_upper_bound_impl() + BOOST_DEDUCED_TYPENAME boost::range_iterator::type + reference(Container& cont) { - test_upper_bound_impl( - upper_bound_policy(), - std::less() - ); - - test_upper_bound_impl( - upper_bound_pred_policy >(), - std::less() - ); - - test_upper_bound_impl( - upper_bound_pred_policy >(), - std::greater() - ); + return std::upper_bound( + cont.begin(), cont.end(), 5, BinaryPredicate()); } + + BinaryPredicate& pred() { return m_pred; } + + private: + BinaryPredicate m_pred; + }; + + template + void test_upper_bound_impl(TestPolicy policy, BinaryPredicate pred) + { + using namespace boost::assign; + + typedef BOOST_DEDUCED_TYPENAME boost::remove_const::type container_t; + typedef BOOST_DEDUCED_TYPENAME Container::value_type value_t; + + boost::range_test::range_return_test_driver test_driver; + + container_t mcont; + Container& cont = mcont; + + test_driver(cont, policy); + + mcont.clear(); + mcont += 1; + + std::vector temp(mcont.begin(), mcont.end()); + std::sort(temp.begin(), temp.end(), pred); + mcont.assign(temp.begin(), temp.end()); + + test_driver(cont, policy); + + mcont.clear(); + mcont += 1,2,3,4,5,6,7,8,9; + + temp.assign(mcont.begin(), mcont.end()); + std::sort(temp.begin(), temp.end(), pred); + mcont.assign(temp.begin(), temp.end()); + + test_driver(cont, policy); + } + + template + void test_upper_bound_impl() + { + test_upper_bound_impl( + upper_bound_policy(), + std::less() + ); + + test_upper_bound_impl( + upper_bound_pred_policy >(), + std::less() + ); + + test_upper_bound_impl( + upper_bound_pred_policy >(), + std::greater() + ); } void test_upper_bound() @@ -179,7 +176,7 @@ init_unit_test_suite(int argc, char* argv[]) boost::unit_test::test_suite* test = BOOST_TEST_SUITE( "RangeTestSuite.algorithm.upper_bound" ); - test->add( BOOST_TEST_CASE( &boost::test_upper_bound ) ); + test->add( BOOST_TEST_CASE( &boost_range_test_algorithm_upper_bound::test_upper_bound ) ); return test; } diff --git a/test/begin.cpp b/test/begin.cpp new file mode 100644 index 0000000..eb745c2 --- /dev/null +++ b/test/begin.cpp @@ -0,0 +1,119 @@ +// Boost.Range library +// +// Copyright Neil Groves 2010. Use, modification and +// distribution is subject to 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) +// +// For more information, see http://www.boost.org/libs/range/ +// + +#include + +#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) +# pragma warn -8091 // supress warning in Boost.Test +# pragma warn -8057 // unused argument argc/argv in Boost.Test +#endif + +#include +#include +#include +#include + +namespace mock_std +{ + template + inline BOOST_DEDUCED_TYPENAME boost::range_iterator::type + begin(SinglePassRange& rng) + { + return rng.begin(); + } + + template + inline BOOST_DEDUCED_TYPENAME boost::range_iterator::type + begin(const SinglePassRange& rng) + { + return rng.begin(); + } + + template + void mock_algorithm_using_begin(const SinglePassRange& rng) + { + BOOST_CHECK( begin(rng) == rng.begin() ); + } + + template + void mock_algorithm_using_begin(SinglePassRange& rng) + { + BOOST_CHECK( begin(rng) == rng.begin() ); + } +} + +namespace boost +{ +#ifdef BOOST_RANGE_SIMULATE_BEGIN_WITHOUT_ADL_NAMESPACE_BARRIER + template + inline BOOST_DEDUCED_TYPENAME range_iterator::type + begin(SinglePassRange& rng) + { + return rng.begin(); + } + + template + inline BOOST_DEDUCED_TYPENAME range_iterator::type + begin(const SinglePassRange& rng) + { + return rng.begin(); + } +#endif + + class MockTestBeginCollection + { + public: + typedef char value_type; + typedef const char* const_pointer; + typedef char* pointer; + typedef const_pointer const_iterator; + typedef pointer iterator; + + MockTestBeginCollection() + : m_first() + , m_last() + { + } + + const_iterator begin() const { return m_first; } + iterator begin() { return m_first; } + const_iterator end() const { return m_last; } + iterator end() { return m_last; } + + private: + iterator m_first; + iterator m_last; + }; +} + +namespace +{ + void test_range_begin() + { + boost::MockTestBeginCollection c; + const boost::MockTestBeginCollection& const_c = c; + mock_std::mock_algorithm_using_begin(const_c); + mock_std::mock_algorithm_using_begin(c); + } +} + +using boost::unit_test_framework::test_suite; + +boost::unit_test_framework::test_suite* +init_unit_test_suite( int argc, char* argv[] ) +{ + boost::unit_test_framework::test_suite* test = BOOST_TEST_SUITE( "Range Test Suite - begin() ADL namespace barrier" ); + + test->add( BOOST_TEST_CASE( &test_range_begin ) ); + + return test; +} + + diff --git a/test/end.cpp b/test/end.cpp new file mode 100644 index 0000000..e3383c3 --- /dev/null +++ b/test/end.cpp @@ -0,0 +1,119 @@ +// Boost.Range library +// +// Copyright Neil Groves 2010. Use, modification and +// distribution is subject to 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) +// +// For more information, see http://www.boost.org/libs/range/ +// + +#include + +#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) +# pragma warn -8091 // supress warning in Boost.Test +# pragma warn -8057 // unused argument argc/argv in Boost.Test +#endif + +#include +#include +#include +#include + +namespace mock_std +{ + template + inline BOOST_DEDUCED_TYPENAME boost::range_iterator::type + end(SinglePassRange& rng) + { + return rng.end(); + } + + template + inline BOOST_DEDUCED_TYPENAME boost::range_iterator::type + end(const SinglePassRange& rng) + { + return rng.end(); + } + + template + void mock_algorithm_using_end(const SinglePassRange& rng) + { + BOOST_CHECK( end(rng) == rng.end() ); + } + + template + void mock_algorithm_using_end(SinglePassRange& rng) + { + BOOST_CHECK( end(rng) == rng.end() ); + } +} + +namespace boost +{ +#ifdef BOOST_RANGE_SIMULATE_END_WITHOUT_ADL_NAMESPACE_BARRIER + template + inline BOOST_DEDUCED_TYPENAME range_iterator::type + end(SinglePassRange& rng) + { + return rng.end(); + } + + template + inline BOOST_DEDUCED_TYPENAME range_iterator::type + end(const SinglePassRange& rng) + { + return rng.end(); + } +#endif + + class MockTestEndCollection + { + public: + typedef char value_type; + typedef const char* const_pointer; + typedef char* pointer; + typedef const_pointer const_iterator; + typedef pointer iterator; + + MockTestEndCollection() + : m_first() + , m_last() + { + } + + const_iterator begin() const { return m_first; } + iterator begin() { return m_first; } + const_iterator end() const { return m_last; } + iterator end() { return m_last; } + + private: + iterator m_first; + iterator m_last; + }; +} + +namespace +{ + void test_range_end_adl_avoidance() + { + boost::MockTestEndCollection c; + const boost::MockTestEndCollection& const_c = c; + mock_std::mock_algorithm_using_end(const_c); + mock_std::mock_algorithm_using_end(c); + } +} + +using boost::unit_test_framework::test_suite; + +boost::unit_test_framework::test_suite* +init_unit_test_suite( int argc, char* argv[] ) +{ + boost::unit_test_framework::test_suite* test = BOOST_TEST_SUITE( "Range Test Suite - end() ADL namespace barrier" ); + + test->add( BOOST_TEST_CASE( &test_range_end_adl_avoidance ) ); + + return test; +} + + diff --git a/test/extension_size.cpp b/test/extension_size.cpp index 988e557..856f87d 100644 --- a/test/extension_size.cpp +++ b/test/extension_size.cpp @@ -24,24 +24,24 @@ namespace boost_range_extension_size_test { - class FooWithoutMemberSize + class FooWithoutSize { typedef std::list impl_t; typedef impl_t::const_iterator const_iterator; typedef impl_t::iterator iterator; public: - friend inline const_iterator range_begin(const FooWithoutMemberSize& obj) { return obj.m_impl.begin(); } - friend inline iterator range_begin(FooWithoutMemberSize& obj) { return obj.m_impl.begin(); } - friend inline const_iterator range_end(const FooWithoutMemberSize& obj) { return obj.m_impl.end(); } - friend inline iterator range_end(FooWithoutMemberSize& obj){ return obj.m_impl.end(); } + friend inline const_iterator range_begin(const FooWithoutSize& obj) { return obj.m_impl.begin(); } + friend inline iterator range_begin(FooWithoutSize& obj) { return obj.m_impl.begin(); } + friend inline const_iterator range_end(const FooWithoutSize& obj) { return obj.m_impl.end(); } + friend inline iterator range_end(FooWithoutSize& obj){ return obj.m_impl.end(); } private: impl_t m_impl; }; - boost::range_difference >::type - inline range_calculate_size(const FooWithoutMemberSize& rng) + inline boost::range_difference >::type + range_calculate_size(const FooWithoutSize& rng) { return 2u; } @@ -49,12 +49,12 @@ namespace boost_range_extension_size_test namespace boost { - template<> struct range_iterator + template<> struct range_iterator { typedef std::list::const_iterator type; }; - template<> struct range_iterator< ::boost_range_extension_size_test::FooWithoutMemberSize > + template<> struct range_iterator< ::boost_range_extension_size_test::FooWithoutSize> { typedef std::list::iterator type; }; @@ -63,13 +63,6 @@ namespace boost namespace { -void check_size_works_with_less_than_random_access() -{ - std::list container; - container.push_back(1); - BOOST_CHECK_EQUAL( boost::size(container), 1u ); -} - void check_size_works_with_random_access() { std::vector container; @@ -77,28 +70,9 @@ void check_size_works_with_random_access() BOOST_CHECK_EQUAL( boost::size(container), 1u ); } -class FooWithMemberSize -{ -public: - typedef std::list impl_t; - typedef impl_t::const_iterator const_iterator; - typedef impl_t::iterator iterator; - typedef impl_t::value_type value_type; - - std::size_t size() const { return 1u; } - const_iterator begin() const { return m_impl.begin(); } - iterator begin() { return m_impl.begin(); } - const_iterator end() const { return m_impl.end(); } - iterator end() { return m_impl.end(); } - -private: - std::list m_impl; -}; - void check_extension_size() { - BOOST_CHECK_EQUAL( boost::size(FooWithMemberSize()), 1u ); - BOOST_CHECK_EQUAL( boost::size(boost_range_extension_size_test::FooWithoutMemberSize()), 2u ); + BOOST_CHECK_EQUAL( boost::size(boost_range_extension_size_test::FooWithoutSize()), 2u ); } } // anonymous namespace @@ -109,14 +83,8 @@ test_suite* init_unit_test_suite( int argc, char* argv[] ) { test_suite* test = BOOST_TEST_SUITE( "Range Test Suite" ); - test->add( BOOST_TEST_CASE( &check_size_works_with_less_than_random_access )); test->add( BOOST_TEST_CASE( &check_size_works_with_random_access )); test->add( BOOST_TEST_CASE( &check_extension_size ) ); return test; } - - - - -