From 55fd3ca5b27223aee514cb1f936724f5f7148bf5 Mon Sep 17 00:00:00 2001 From: Neil Groves Date: Sat, 1 Jan 2011 16:46:32 +0000 Subject: [PATCH] [boost][range] - Updated begin/end to be protected against accidental ADL to improve compatibility with C++0x. Added any_range which adds type erasure support. Added a type_erased adaptor to utilise the any_range. Implemented the any_iterator using a small buffer optimization to avoid heap usage. [SVN r67541] --- 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 | 6 +- .../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 +- 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/type_erased.qbk | 151 +++++ doc/reference/ranges.qbk | 1 + doc/reference/ranges/any_range.qbk | 115 ++++ include/boost/range/adaptor/sliced.hpp | 1 + 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 | 119 ++++ .../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/end.hpp | 23 +- test/Jamfile.v2 | 4 + test/adaptor_test/type_erased.cpp | 487 +++++++++++++++ test/adaptor_test/type_erased_example.cpp | 115 ++++ test/begin.cpp | 119 ++++ test/end.cpp | 119 ++++ 122 files changed, 4087 insertions(+), 594 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 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 dd72835..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 26, 2010 at 20:24:07 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 8e05a64..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 ae552a4..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 be65866..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 5a50b04..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 207c57c..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 29c6173..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 d3c86a1..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 633143c..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 7eff9ad..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 c28ac99..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
@@ -143,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 24ad929..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 28b2136..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 dd04458..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 67704a1..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 3f3b716..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 0666568..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 5c0d18c..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 a9d046e..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 0ae40e3..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 f016299..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 5ace880..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 8f7dca5..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 4680deb..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 3096601..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 46ecde7..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 7a9359f..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 69ef4fe..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 0d5c74b..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 5fed73d..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 c113746..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 9d32712..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 663d200..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 f48c04c..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 1fa1212..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 0792e40..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 686c674..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 13faf01..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 3c60584..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 d9db715..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 7bb21a3..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 ae53329..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 a5438e8..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 10334bd..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 780d610..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 993178e..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 914cbc2..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 1a71131..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 acd7dc4..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 4592a49..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 4410229..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 8bca784..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 aab0de6..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 f89862c..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 74a8087..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 87f2032..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 8a55028..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 986e721..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 ebd8888..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 fb19ad7..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 0c6e838..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 77c6b73..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 5528c72..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 f214649..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 7d316e6..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 276904a..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 7634734..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 d02c38c..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 6143c5d..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 a1189a7..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 405e71e..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 7863b41..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 3e6b199..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 15baa4b..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 79a990d..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 a2bef01..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 9b1369f..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 99c847a..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 01bf416..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 440ba3f..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 a7ecfa6..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 51c2b73..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 a54c8f6..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 b8ee14f..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 00311d3..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 14bd666..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 007a58d..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/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
+
any_range
counting_range
istream_range
irange
@@ -42,7 +43,7 @@
-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 c6e6d60..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 ca18ddd..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 dea3138..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 4e555e0..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 a8032ca..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 ec320e9..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/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/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/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..986ea1a --- /dev/null +++ b/include/boost/range/detail/any_iterator_buffer.hpp @@ -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/ +// +#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 + +#undef BOOST_TEST_MESSAGE + +#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/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/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/type_erased.cpp b/test/adaptor_test/type_erased.cpp new file mode 100644 index 0000000..a697c52 --- /dev/null +++ b/test/adaptor_test/type_erased.cpp @@ -0,0 +1,487 @@ +// 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 +{ + namespace + { + class MockType + { + public: + explicit MockType(int x) + : m_x(x) {} + + int get() const { return m_x; } + + bool operator==(const MockType& other) const + { + return m_x == other.m_x; + } + + bool operator!=(const MockType& other) const + { + return m_x != other.m_x; + } + + private: + int m_x; + }; + + 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; + + type_erased_t type_erased_ex; + + Container source; + for (int i = 0; i < 100; ++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_ex; + BOOST_CHECK_EQUAL_COLLECTIONS( source.begin(), source.end(), + r.begin(), r.end() ); + r = mutable_any_range(); + + r = boost::adaptors::type_erase(source, type_erased_ex); + 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_ex; + 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_ex; + 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_ex); + 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<4> >()(); + test_type_erased_impl_fn< Container, Traversal, any_iterator_buffer<8> >()(); + test_type_erased_impl_fn< Container, Traversal, any_iterator_buffer<16> >()(); + 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_buffer<4096> >()(); + test_type_erased_impl_fn< Container, Traversal, any_iterator_buffer<16384> >()(); + test_type_erased_impl_fn< Container, Traversal, any_iterator_stack_only_buffer<128> >()(); + test_type_erased_impl_fn< Container, Traversal, any_iterator_stack_only_buffer<4096> >()(); + test_type_erased_impl_fn< Container, Traversal, any_iterator_stack_only_buffer<16384> >()(); + } + + 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() ); + } + + class MockInt + { + public: + MockInt() : m_value() {} + MockInt(int x) : m_value(x) {} + operator int() const { return m_value; } + private: + int m_value; + }; + + + 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, MockInt, char, const MockInt&, short, const MockInt& >(); + + // 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); + + for (int i = 0; i < 10; ++i) + { + BOOST_CHECK_EQUAL( (c | type_erased_t())[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/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; +} + +