Merge branch 'develop'

This commit is contained in:
Neil Groves
2018-04-18 11:04:16 +01:00
36 changed files with 657 additions and 125 deletions

View File

@@ -7,7 +7,7 @@
[section Overview] [section Overview]
A Range is a [*/concept/] similar to the STL [@http://www.sgi.com/Technology/STL/Container.html Container] concept. A Range provides iterators for accessing a half-open range `[first,one_past_last)` of elements and provides information about the number of elements in the Range. However, a Range has fewer requirements than a Container. A Range is a [*/concept/] similar to the STL [@http://www.sgi.com/tech/stl/Container.html Container] concept. A Range provides iterators for accessing a half-open range `[first,one_past_last)` of elements and provides information about the number of elements in the Range. However, a Range has fewer requirements than a Container.
The motivation for the Range concept is that there are many useful Container-like types that do not meet the full requirements of Container, and many algorithms that can be written with this reduced set of requirements. In particular, a Range does not necessarily The motivation for the Range concept is that there are many useful Container-like types that do not meet the full requirements of Container, and many algorithms that can be written with this reduced set of requirements. In particular, a Range does not necessarily

View File

@@ -46,7 +46,7 @@
[[`<boost/range/adaptor/copied.hpp>`] [__range_adaptors_copied__]] [[`<boost/range/adaptor/copied.hpp>`] [__range_adaptors_copied__]]
[[`<boost/range/adaptor/filtered.hpp>`] [__range_adaptors_filtered__]] [[`<boost/range/adaptor/filtered.hpp>`] [__range_adaptors_filtered__]]
[[`<boost/range/adaptor/indexed.hpp>`] [__range_adaptors_indexed__]] [[`<boost/range/adaptor/indexed.hpp>`] [__range_adaptors_indexed__]]
[[`<boost/range/adaptor/indirected.hpp.`] [__range_adaptors_indirected__]] [[`<boost/range/adaptor/indirected.hpp>`] [__range_adaptors_indirected__]]
[[`<boost/range/adaptor/map.hpp>`] [__range_adaptors_map_keys__ __range_adaptors_map_values__]] [[`<boost/range/adaptor/map.hpp>`] [__range_adaptors_map_keys__ __range_adaptors_map_values__]]
[[`<boost/range/adaptor/replaced.hpp>`] [__range_adaptors_replaced__]] [[`<boost/range/adaptor/replaced.hpp>`] [__range_adaptors_replaced__]]
[[`<boost/range/adaptor/replaced_if.hpp>`] [__range_adaptors_replaced_if__]] [[`<boost/range/adaptor/replaced_if.hpp>`] [__range_adaptors_replaced_if__]]

View File

@@ -172,6 +172,7 @@ rng | boost::adaptors::adaptor_generator
[include adaptors/indirected.qbk] [include adaptors/indirected.qbk]
[include adaptors/map_keys.qbk] [include adaptors/map_keys.qbk]
[include adaptors/map_values.qbk] [include adaptors/map_values.qbk]
[include adaptors/ref_unwrapped.qbk]
[include adaptors/replaced.qbk] [include adaptors/replaced.qbk]
[include adaptors/replaced_if.qbk] [include adaptors/replaced_if.qbk]
[include adaptors/reversed.qbk] [include adaptors/reversed.qbk]

View File

@@ -0,0 +1,32 @@
[/
Copyright 2015 Robin Eckert
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:ref_unwrapped ref_unwrapped]
[table
[[Syntax] [Code]]
[[Pipe] [`rng | boost::adaptors::ref_unwrapped`]]
[[Function] [`boost::adaptors::ref_unwrap(rng)`]]
]
This adaptor produces a range than applies `.get()` on all values in
the range. It is useful for iterating ranges of
`std::reference_wrapper` values or values using similar semantics.
The adaptor is C++11 (and above) only.
* [*Precondition:] The `value_type` of the range has a `.get() const`.
* [*Postcondition:] For all elements `x` in the returned range, `x` is the result of `y.get()` where `y` is the corresponding element in the original range.
* [*Range Category:] __single_pass_range__
* [*Range Return Type:] `boost::unwrap_ref_range<decltype(rng)>`
* [*Returned Range Category:] The range category of `rng`.
[section:ref_unwrapped_example ref_unwrapped example]
[import ../../../test/adaptor_test/ref_unwrapped_example.cpp]
[ref_unwrapped_example]
[endsect]
This would produce the output `123`.
[endsect]

View File

@@ -7,8 +7,8 @@
[table [table
[[Syntax] [Code]] [[Syntax] [Code]]
[[Pipe] [`rng | boost::adaptors::replaced(new_value, old_value)`]] [[Pipe] [`rng | boost::adaptors::replaced(old_value, new_value)`]]
[[Function] [`boost::adaptors::replace(rng, new_value, old_value)`]] [[Function] [`boost::adaptors::replace(rng, old_value, new_value)`]]
] ]
* [*Precondition:] * [*Precondition:]

View File

@@ -10,7 +10,11 @@
`` ``
template<class Integer> template<class Integer>
iterator_range< range_detail::integer_iterator<Integer> > iterator_range< range_detail::integer_iterator<Integer> >
irange(Integer first, Integer last); irange(Integer last);
template<class Integer>
iterator_range< range_detail::integer_iterator<Integer> >
irange(Integer first, Integer last);
template<class Integer, class StepSize> template<class Integer, class StepSize>
iterator_range< range_detail::integer_iterator_with_step<Integer, StepSize> > iterator_range< range_detail::integer_iterator_with_step<Integer, StepSize> >
@@ -37,4 +41,3 @@ Defined in the header file `boost/range/irange.hpp`
Constant. Since this function generates a new range the most significant performance cost is incurred through the iteration of the generated range. Constant. Since this function generates a new range the most significant performance cost is incurred through the iteration of the generated range.
[endsect] [endsect]

View File

@@ -181,7 +181,7 @@ namespace boost
} }
template< class ForwardRng, class BinPredicate > template< class ForwardRng, class BinPredicate >
inline adjacent_filtered_range<BinPredicate, ForwardRng, false> inline adjacent_filtered_range<BinPredicate, const ForwardRng, false>
operator|( const ForwardRng& r, operator|( const ForwardRng& r,
const adjacent_excl_holder<BinPredicate>& f ) const adjacent_excl_holder<BinPredicate>& f )
{ {

View File

@@ -0,0 +1,102 @@
// Boost.Range library
//
// Copyright Robin Eckert 2015.
// Copyright Thorsten Ottosen, Neil Groves 2006 - 2008. 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_ADAPTOR_REF_UNWRAPPED_HPP
#define BOOST_RANGE_ADAPTOR_REF_UNWRAPPED_HPP
#include <boost/range/adaptor/transformed.hpp>
#include <boost/range/reference.hpp>
#include <boost/range/concepts.hpp>
#include <utility>
#if !defined(BOOST_NO_CXX11_DECLTYPE)
namespace boost
{
namespace range_detail
{
struct ref_unwrapped_forwarder {};
template<class SinglePassRange>
struct unwrap_ref
{
typedef BOOST_DEDUCED_TYPENAME
range_reference<SinglePassRange>::type argument_type;
using result_type = decltype(std::declval<argument_type>().get() );
result_type operator()( argument_type &&r ) const
{
return r.get();
}
};
template<class SinglePassRange>
class unwrap_ref_range
: public transformed_range<unwrap_ref<SinglePassRange>,
SinglePassRange>
{
using base = transformed_range<unwrap_ref<SinglePassRange>,
SinglePassRange>;
public:
using transform_fn_type = unwrap_ref<SinglePassRange>;
using source_range_type = SinglePassRange;
unwrap_ref_range(transform_fn_type fn, source_range_type &rng)
: base(fn, rng)
{
}
unwrap_ref_range(const base &other) : base(other) {}
};
template<class SinglePassRange>
inline unwrap_ref_range<SinglePassRange>
operator|(SinglePassRange& r, ref_unwrapped_forwarder)
{
BOOST_RANGE_CONCEPT_ASSERT((
SinglePassRangeConcept<SinglePassRange>));
return operator|( r,
boost::adaptors::transformed(unwrap_ref<SinglePassRange>()));
}
}
using range_detail::unwrap_ref_range;
namespace adaptors
{
namespace
{
const range_detail::ref_unwrapped_forwarder ref_unwrapped =
range_detail::ref_unwrapped_forwarder();
}
template<class SinglePassRange>
inline unwrap_ref_range<SinglePassRange>
ref_unwrap(SinglePassRange& rng)
{
BOOST_RANGE_CONCEPT_ASSERT((
SinglePassRangeConcept<SinglePassRange>));
return unwrap_ref_range<SinglePassRange>(
range_detail::unwrap_ref<SinglePassRange>(), rng );
}
} // 'adaptors'
}
#endif
#endif

View File

@@ -101,12 +101,9 @@ namespace boost
void operator=(const replace_holder&); void operator=(const replace_holder&);
}; };
template< class SinglePassRange > template< class SinglePassRange, class Value >
inline replaced_range<SinglePassRange> inline replaced_range<SinglePassRange>
operator|( operator|(SinglePassRange& r, const replace_holder<Value>& f)
SinglePassRange& r,
const replace_holder<
BOOST_DEDUCED_TYPENAME range_value<SinglePassRange>::type>& f )
{ {
BOOST_RANGE_CONCEPT_ASSERT(( BOOST_RANGE_CONCEPT_ASSERT((
SinglePassRangeConcept<SinglePassRange>)); SinglePassRangeConcept<SinglePassRange>));
@@ -114,12 +111,9 @@ namespace boost
return replaced_range<SinglePassRange>(r, f.val1, f.val2); return replaced_range<SinglePassRange>(r, f.val1, f.val2);
} }
template< class SinglePassRange > template< class SinglePassRange, class Value >
inline replaced_range<const SinglePassRange> inline replaced_range<const SinglePassRange>
operator|( operator|(const SinglePassRange& r, const replace_holder<Value>& f)
const SinglePassRange& r,
const replace_holder<
BOOST_DEDUCED_TYPENAME range_value<SinglePassRange>::type>& f)
{ {
BOOST_RANGE_CONCEPT_ASSERT(( BOOST_RANGE_CONCEPT_ASSERT((
SinglePassRangeConcept<const SinglePassRange>)); SinglePassRangeConcept<const SinglePassRange>));
@@ -139,11 +133,9 @@ namespace boost
range_detail::forwarder2<range_detail::replace_holder>(); range_detail::forwarder2<range_detail::replace_holder>();
} }
template<class SinglePassRange> template< class SinglePassRange, class Value >
inline replaced_range<SinglePassRange> inline replaced_range<SinglePassRange>
replace(SinglePassRange& rng, replace(SinglePassRange& rng, Value from, Value to)
BOOST_DEDUCED_TYPENAME range_value<SinglePassRange>::type from,
BOOST_DEDUCED_TYPENAME range_value<SinglePassRange>::type to)
{ {
BOOST_RANGE_CONCEPT_ASSERT(( BOOST_RANGE_CONCEPT_ASSERT((
SinglePassRangeConcept<SinglePassRange>)); SinglePassRangeConcept<SinglePassRange>));
@@ -151,11 +143,9 @@ namespace boost
return replaced_range<SinglePassRange>(rng, from, to); return replaced_range<SinglePassRange>(rng, from, to);
} }
template<class SinglePassRange> template< class SinglePassRange, class Value >
inline replaced_range<const SinglePassRange> inline replaced_range<const SinglePassRange>
replace(const SinglePassRange& rng, replace(const SinglePassRange& rng, Value from, Value to)
BOOST_DEDUCED_TYPENAME range_value<SinglePassRange>::type from,
BOOST_DEDUCED_TYPENAME range_value<SinglePassRange>::type to)
{ {
BOOST_RANGE_CONCEPT_ASSERT(( BOOST_RANGE_CONCEPT_ASSERT((
SinglePassRangeConcept<const SinglePassRange>)); SinglePassRangeConcept<const SinglePassRange>));

View File

@@ -103,13 +103,9 @@ namespace boost
T m_to; T m_to;
}; };
template< class Pred, class SinglePassRange > template< class Pred, class SinglePassRange, class Value >
inline replaced_if_range<Pred, SinglePassRange> inline replaced_if_range<Pred, SinglePassRange>
operator|( operator|(SinglePassRange& r, const replace_if_holder<Pred, Value>& f)
SinglePassRange& r,
const replace_if_holder<
Pred,
BOOST_DEDUCED_TYPENAME range_value<SinglePassRange>::type>& f)
{ {
BOOST_RANGE_CONCEPT_ASSERT(( BOOST_RANGE_CONCEPT_ASSERT((
SinglePassRangeConcept<SinglePassRange>)); SinglePassRangeConcept<SinglePassRange>));
@@ -118,13 +114,9 @@ namespace boost
r, f.pred(), f.to()); r, f.pred(), f.to());
} }
template< class Pred, class SinglePassRange > template< class Pred, class SinglePassRange, class Value >
inline replaced_if_range<Pred, const SinglePassRange> inline replaced_if_range<Pred, const SinglePassRange>
operator|( operator|(const SinglePassRange& r, const replace_if_holder<Pred, Value>& f)
const SinglePassRange& r,
const replace_if_holder<
Pred,
BOOST_DEDUCED_TYPENAME range_value<SinglePassRange>::type>& f)
{ {
BOOST_RANGE_CONCEPT_ASSERT(( BOOST_RANGE_CONCEPT_ASSERT((
SinglePassRangeConcept<const SinglePassRange>)); SinglePassRangeConcept<const SinglePassRange>));
@@ -145,10 +137,9 @@ namespace boost
range_detail::forwarder2TU<range_detail::replace_if_holder>(); range_detail::forwarder2TU<range_detail::replace_if_holder>();
} }
template<class Pred, class SinglePassRange> template< class Pred, class SinglePassRange, class Value >
inline replaced_if_range<Pred, SinglePassRange> inline replaced_if_range<Pred, SinglePassRange>
replace_if(SinglePassRange& rng, Pred pred, replace_if(SinglePassRange& rng, Pred pred, Value to)
BOOST_DEDUCED_TYPENAME range_value<SinglePassRange>::type to)
{ {
BOOST_RANGE_CONCEPT_ASSERT(( BOOST_RANGE_CONCEPT_ASSERT((
SinglePassRangeConcept<SinglePassRange>)); SinglePassRangeConcept<SinglePassRange>));
@@ -157,12 +148,9 @@ namespace boost
rng, pred, to); rng, pred, to);
} }
template<class Pred, class SinglePassRange> template< class Pred, class SinglePassRange, class Value >
inline replaced_if_range<Pred, const SinglePassRange> inline replaced_if_range<Pred, const SinglePassRange>
replace_if( replace_if(const SinglePassRange& rng, Pred pred, Value to)
const SinglePassRange& rng,
Pred pred,
BOOST_DEDUCED_TYPENAME range_value<const SinglePassRange>::type to)
{ {
BOOST_RANGE_CONCEPT_ASSERT(( BOOST_RANGE_CONCEPT_ASSERT((
SinglePassRangeConcept<const SinglePassRange>)); SinglePassRangeConcept<const SinglePassRange>));

View File

@@ -9,12 +9,12 @@
#ifndef BOOST_RANGE_ALGORITHM_MAX_ELEMENT_HPP_INCLUDED #ifndef BOOST_RANGE_ALGORITHM_MAX_ELEMENT_HPP_INCLUDED
#define BOOST_RANGE_ALGORITHM_MAX_ELEMENT_HPP_INCLUDED #define BOOST_RANGE_ALGORITHM_MAX_ELEMENT_HPP_INCLUDED
#include <boost/algorithm/minmax_element.hpp>
#include <boost/concept_check.hpp> #include <boost/concept_check.hpp>
#include <boost/range/begin.hpp> #include <boost/range/begin.hpp>
#include <boost/range/end.hpp> #include <boost/range/end.hpp>
#include <boost/range/concepts.hpp> #include <boost/range/concepts.hpp>
#include <boost/range/detail/range_return.hpp> #include <boost/range/detail/range_return.hpp>
#include <algorithm>
namespace boost namespace boost
{ {
@@ -32,7 +32,7 @@ inline BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
max_element(ForwardRange& rng) max_element(ForwardRange& rng)
{ {
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> )); BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
return std::max_element(boost::begin(rng), boost::end(rng)); return boost::first_max_element(boost::begin(rng), boost::end(rng));
} }
/// \overload /// \overload
@@ -41,7 +41,7 @@ inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type
max_element(const ForwardRange& rng) max_element(const ForwardRange& rng)
{ {
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> )); BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
return std::max_element(boost::begin(rng), boost::end(rng)); return boost::first_max_element(boost::begin(rng), boost::end(rng));
} }
/// \overload /// \overload
@@ -50,7 +50,7 @@ inline BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
max_element(ForwardRange& rng, BinaryPredicate pred) max_element(ForwardRange& rng, BinaryPredicate pred)
{ {
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> )); BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
return std::max_element(boost::begin(rng), boost::end(rng), pred); return boost::first_max_element(boost::begin(rng), boost::end(rng), pred);
} }
/// \overload /// \overload
@@ -59,7 +59,7 @@ inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type
max_element(const ForwardRange& rng, BinaryPredicate pred) max_element(const ForwardRange& rng, BinaryPredicate pred)
{ {
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> )); BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
return std::max_element(boost::begin(rng), boost::end(rng), pred); return boost::first_max_element(boost::begin(rng), boost::end(rng), pred);
} }
// range_return overloads // range_return overloads
@@ -71,7 +71,7 @@ max_element(ForwardRange& rng)
{ {
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> )); BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
return range_return<ForwardRange,re>::pack( return range_return<ForwardRange,re>::pack(
std::max_element(boost::begin(rng), boost::end(rng)), boost::first_max_element(boost::begin(rng), boost::end(rng)),
rng); rng);
} }
@@ -82,7 +82,7 @@ max_element(const ForwardRange& rng)
{ {
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> )); BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
return range_return<const ForwardRange,re>::pack( return range_return<const ForwardRange,re>::pack(
std::max_element(boost::begin(rng), boost::end(rng)), boost::first_max_element(boost::begin(rng), boost::end(rng)),
rng); rng);
} }
@@ -93,7 +93,7 @@ max_element(ForwardRange& rng, BinaryPredicate pred)
{ {
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> )); BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
return range_return<ForwardRange,re>::pack( return range_return<ForwardRange,re>::pack(
std::max_element(boost::begin(rng), boost::end(rng), pred), boost::first_max_element(boost::begin(rng), boost::end(rng), pred),
rng); rng);
} }
@@ -104,7 +104,7 @@ max_element(const ForwardRange& rng, BinaryPredicate pred)
{ {
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> )); BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
return range_return<const ForwardRange,re>::pack( return range_return<const ForwardRange,re>::pack(
std::max_element(boost::begin(rng), boost::end(rng), pred), boost::first_max_element(boost::begin(rng), boost::end(rng), pred),
rng); rng);
} }

View File

@@ -9,12 +9,12 @@
#ifndef BOOST_RANGE_ALGORITHM_MIN_ELEMENT_HPP_INCLUDED #ifndef BOOST_RANGE_ALGORITHM_MIN_ELEMENT_HPP_INCLUDED
#define BOOST_RANGE_ALGORITHM_MIN_ELEMENT_HPP_INCLUDED #define BOOST_RANGE_ALGORITHM_MIN_ELEMENT_HPP_INCLUDED
#include <boost/algorithm/minmax_element.hpp>
#include <boost/concept_check.hpp> #include <boost/concept_check.hpp>
#include <boost/range/begin.hpp> #include <boost/range/begin.hpp>
#include <boost/range/end.hpp> #include <boost/range/end.hpp>
#include <boost/range/concepts.hpp> #include <boost/range/concepts.hpp>
#include <boost/range/detail/range_return.hpp> #include <boost/range/detail/range_return.hpp>
#include <algorithm>
namespace boost namespace boost
{ {
@@ -32,7 +32,7 @@ inline BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
min_element(ForwardRange& rng) min_element(ForwardRange& rng)
{ {
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> )); BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
return std::min_element(boost::begin(rng), boost::end(rng)); return boost::first_min_element(boost::begin(rng), boost::end(rng));
} }
/// \overload /// \overload
@@ -41,7 +41,7 @@ inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type
min_element(const ForwardRange& rng) min_element(const ForwardRange& rng)
{ {
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> )); BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
return std::min_element(boost::begin(rng), boost::end(rng)); return boost::first_min_element(boost::begin(rng), boost::end(rng));
} }
/// \overload /// \overload
@@ -50,7 +50,7 @@ inline BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type
min_element(ForwardRange& rng, BinaryPredicate pred) min_element(ForwardRange& rng, BinaryPredicate pred)
{ {
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> )); BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
return std::min_element(boost::begin(rng), boost::end(rng), pred); return boost::first_min_element(boost::begin(rng), boost::end(rng), pred);
} }
/// \overload /// \overload
@@ -59,7 +59,7 @@ inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type
min_element(const ForwardRange& rng, BinaryPredicate pred) min_element(const ForwardRange& rng, BinaryPredicate pred)
{ {
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> )); BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
return std::min_element(boost::begin(rng), boost::end(rng), pred); return boost::first_min_element(boost::begin(rng), boost::end(rng), pred);
} }
// range_return overloads // range_return overloads
@@ -71,7 +71,7 @@ min_element(ForwardRange& rng)
{ {
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> )); BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
return range_return<ForwardRange,re>::pack( return range_return<ForwardRange,re>::pack(
std::min_element(boost::begin(rng), boost::end(rng)), boost::first_min_element(boost::begin(rng), boost::end(rng)),
rng); rng);
} }
@@ -82,7 +82,7 @@ min_element(const ForwardRange& rng)
{ {
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> )); BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
return range_return<const ForwardRange,re>::pack( return range_return<const ForwardRange,re>::pack(
std::min_element(boost::begin(rng), boost::end(rng)), boost::first_min_element(boost::begin(rng), boost::end(rng)),
rng); rng);
} }
@@ -93,7 +93,7 @@ min_element(ForwardRange& rng, BinaryPredicate pred)
{ {
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> )); BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
return range_return<ForwardRange,re>::pack( return range_return<ForwardRange,re>::pack(
std::min_element(boost::begin(rng), boost::end(rng), pred), boost::first_min_element(boost::begin(rng), boost::end(rng), pred),
rng); rng);
} }
@@ -104,7 +104,7 @@ min_element(const ForwardRange& rng, BinaryPredicate pred)
{ {
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> )); BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
return range_return<const ForwardRange,re>::pack( return range_return<const ForwardRange,re>::pack(
std::min_element(boost::begin(rng), boost::end(rng), pred), boost::first_min_element(boost::begin(rng), boost::end(rng), pred),
rng); rng);
} }

View File

@@ -14,12 +14,85 @@
#include <boost/range/end.hpp> #include <boost/range/end.hpp>
#include <boost/range/concepts.hpp> #include <boost/range/concepts.hpp>
#include <algorithm> #include <algorithm>
#ifdef BOOST_NO_CXX98_RANDOM_SHUFFLE
#include <cstdlib>
#endif
namespace boost namespace boost
{ {
namespace range namespace range
{ {
namespace detail
{
#ifdef BOOST_NO_CXX98_RANDOM_SHUFFLE
// wrap std::rand as UniformRandomBitGenerator
struct wrap_rand
{
typedef unsigned int result_type;
static result_type (min)()
{
return 0;
}
static result_type (max)()
{
return RAND_MAX;
}
result_type operator()()
{
return std::rand();
}
};
template< class RandomIt >
inline void random_shuffle(RandomIt first, RandomIt last)
{
std::shuffle(first, last, wrap_rand());
}
// wrap Generator as UniformRandomBitGenerator
template< class Generator >
struct wrap_generator
{
typedef unsigned int result_type;
static const int max_arg = ((0u - 1u) >> 2) + 1;
Generator& g;
wrap_generator(Generator& gen) : g(gen) {}
static result_type (min)()
{
return 0;
}
static result_type (max)()
{
return max_arg - 1;
}
result_type operator()()
{
return static_cast<result_type>(g(max_arg));
}
};
template< class RandomIt, class Generator >
inline void random_shuffle(RandomIt first, RandomIt last, Generator& gen)
{
std::shuffle(first, last, wrap_generator< Generator >(gen));
}
#else
using std::random_shuffle;
#endif
} // namespace detail
/// \brief template function random_shuffle /// \brief template function random_shuffle
/// ///
/// range-based version of the random_shuffle std algorithm /// range-based version of the random_shuffle std algorithm
@@ -30,7 +103,7 @@ template<class RandomAccessRange>
inline RandomAccessRange& random_shuffle(RandomAccessRange& rng) inline RandomAccessRange& random_shuffle(RandomAccessRange& rng)
{ {
BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> )); BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
std::random_shuffle(boost::begin(rng), boost::end(rng)); detail::random_shuffle(boost::begin(rng), boost::end(rng));
return rng; return rng;
} }
@@ -39,7 +112,7 @@ template<class RandomAccessRange>
inline const RandomAccessRange& random_shuffle(const RandomAccessRange& rng) inline const RandomAccessRange& random_shuffle(const RandomAccessRange& rng)
{ {
BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> )); BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
std::random_shuffle(boost::begin(rng), boost::end(rng)); detail::random_shuffle(boost::begin(rng), boost::end(rng));
return rng; return rng;
} }
@@ -48,7 +121,7 @@ template<class RandomAccessRange, class Generator>
inline RandomAccessRange& random_shuffle(RandomAccessRange& rng, Generator& gen) inline RandomAccessRange& random_shuffle(RandomAccessRange& rng, Generator& gen)
{ {
BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> )); BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<RandomAccessRange> ));
std::random_shuffle(boost::begin(rng), boost::end(rng), gen); detail::random_shuffle(boost::begin(rng), boost::end(rng), gen);
return rng; return rng;
} }
@@ -57,7 +130,7 @@ template<class RandomAccessRange, class Generator>
inline const RandomAccessRange& random_shuffle(const RandomAccessRange& rng, Generator& gen) inline const RandomAccessRange& random_shuffle(const RandomAccessRange& rng, Generator& gen)
{ {
BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> )); BOOST_RANGE_CONCEPT_ASSERT(( RandomAccessRangeConcept<const RandomAccessRange> ));
std::random_shuffle(boost::begin(rng), boost::end(rng), gen); detail::random_shuffle(boost::begin(rng), boost::end(rng), gen);
return rng; return rng;
} }

View File

@@ -39,6 +39,7 @@ inline Container& insert( Container& on, const Range& from )
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<Container> )); BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<Container> ));
BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<Range> )); BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<Range> ));
on.insert(boost::begin(from), boost::end(from)); on.insert(boost::begin(from), boost::end(from));
return on;
} }
} // namespace range } // namespace range

View File

@@ -25,6 +25,11 @@
#include <boost/detail/workaround.hpp> #include <boost/detail/workaround.hpp>
#include <cstring> #include <cstring>
#if !defined(BOOST_NO_CXX11_CHAR16_T) || !defined(BOOST_NO_CXX11_CHAR32_T)
#include <string> // for std::char_traits
#endif
#ifndef BOOST_NO_CWCHAR #ifndef BOOST_NO_CWCHAR
#include <cwchar> #include <cwchar>
#endif #endif
@@ -38,6 +43,20 @@ namespace boost
return strlen( s ); return strlen( s );
} }
#ifndef BOOST_NO_CXX11_CHAR16_T
inline std::size_t length( const char16_t* s )
{
return std::char_traits<char16_t>::length( s );
}
#endif
#ifndef BOOST_NO_CXX11_CHAR32_T
inline std::size_t length( const char32_t* s )
{
return std::char_traits<char32_t>::length( s );
}
#endif
#ifndef BOOST_NO_CWCHAR #ifndef BOOST_NO_CWCHAR
inline std::size_t length( const wchar_t* s ) inline std::size_t length( const wchar_t* s )
{ {
@@ -61,6 +80,30 @@ namespace boost
return true; return true;
} }
#ifndef BOOST_NO_CXX11_CHAR16_T
inline bool is_char_ptr( char16_t* )
{
return true;
}
inline bool is_char_ptr( const char16_t* )
{
return true;
}
#endif
#ifndef BOOST_NO_CXX11_CHAR32_T
inline bool is_char_ptr( char32_t* )
{
return true;
}
inline bool is_char_ptr( const char32_t* )
{
return true;
}
#endif
#ifndef BOOST_NO_CWCHAR #ifndef BOOST_NO_CWCHAR
inline bool is_char_ptr( wchar_t* ) inline bool is_char_ptr( wchar_t* )
{ {

View File

@@ -36,7 +36,7 @@ namespace range_detail
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
template< typename C > template< typename C >
inline BOOST_DEDUCED_TYPENAME range_iterator<C>::type BOOST_CONSTEXPR inline BOOST_DEDUCED_TYPENAME range_iterator<C>::type
range_begin( C& c ) range_begin( C& c )
{ {
// //
@@ -52,13 +52,13 @@ namespace range_detail
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
template< typename Iterator > template< typename Iterator >
inline Iterator range_begin( const std::pair<Iterator,Iterator>& p ) BOOST_CONSTEXPR inline Iterator range_begin( const std::pair<Iterator,Iterator>& p )
{ {
return p.first; return p.first;
} }
template< typename Iterator > template< typename Iterator >
inline Iterator range_begin( std::pair<Iterator,Iterator>& p ) BOOST_CONSTEXPR inline Iterator range_begin( std::pair<Iterator,Iterator>& p )
{ {
return p.first; return p.first;
} }
@@ -71,13 +71,13 @@ namespace range_detail
// May this be discarded? Or is it needed for bad compilers? // May this be discarded? Or is it needed for bad compilers?
// //
template< typename T, std::size_t sz > template< typename T, std::size_t sz >
inline const T* range_begin( const T (&a)[sz] ) BOOST_CONSTEXPR inline const T* range_begin( const T (&a)[sz] ) BOOST_NOEXCEPT
{ {
return a; return a;
} }
template< typename T, std::size_t sz > template< typename T, std::size_t sz >
inline T* range_begin( T (&a)[sz] ) BOOST_CONSTEXPR inline T* range_begin( T (&a)[sz] ) BOOST_NOEXCEPT
{ {
return a; return a;
} }
@@ -94,7 +94,7 @@ namespace range_adl_barrier
{ {
template< class T > template< class T >
inline BOOST_DEDUCED_TYPENAME range_iterator<T>::type begin( T& r ) BOOST_CONSTEXPR inline BOOST_DEDUCED_TYPENAME range_iterator<T>::type begin( T& r )
{ {
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
using namespace range_detail; using namespace range_detail;
@@ -103,7 +103,7 @@ inline BOOST_DEDUCED_TYPENAME range_iterator<T>::type begin( T& r )
} }
template< class T > template< class T >
inline BOOST_DEDUCED_TYPENAME range_iterator<const T>::type begin( const T& r ) BOOST_CONSTEXPR inline BOOST_DEDUCED_TYPENAME range_iterator<const T>::type begin( const T& r )
{ {
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
using namespace range_detail; using namespace range_detail;

View File

@@ -252,7 +252,12 @@ namespace boost {
n = i - j; n = i - j;
} }
private: private:
// MSVC 14.1 - avoid C4596: 'difference_type': illegal qualified name in member declaration
#if defined(_MSC_VER) && _MSC_VER >= 1912
BOOST_DEDUCED_TYPENAME difference_type n;
#else
BOOST_DEDUCED_TYPENAME RandomAccessIteratorConcept::difference_type n; BOOST_DEDUCED_TYPENAME RandomAccessIteratorConcept::difference_type n;
#endif
Iterator i; Iterator i;
Iterator j; Iterator j;
#endif #endif

View File

@@ -32,7 +32,7 @@ namespace boost
struct range_begin<std_container_> struct range_begin<std_container_>
{ {
template< typename C > template< typename C >
static BOOST_RANGE_DEDUCED_TYPENAME range_iterator<C>::type fun( C& c ) BOOST_CONSTEXPR static BOOST_RANGE_DEDUCED_TYPENAME range_iterator<C>::type fun( C& c )
{ {
return c.begin(); return c.begin();
}; };
@@ -46,7 +46,7 @@ namespace boost
struct range_begin<std_pair_> struct range_begin<std_pair_>
{ {
template< typename P > template< typename P >
static BOOST_RANGE_DEDUCED_TYPENAME range_iterator<P>::type fun( const P& p ) BOOST_CONSTEXPR static BOOST_RANGE_DEDUCED_TYPENAME range_iterator<P>::type fun( const P& p )
{ {
return p.first; return p.first;
} }
@@ -60,7 +60,7 @@ namespace boost
struct range_begin<array_> struct range_begin<array_>
{ {
template<typename T> template<typename T>
static BOOST_RANGE_DEDUCED_TYPENAME range_value<T>::type* fun(T& t) BOOST_CONSTEXPR static BOOST_RANGE_DEDUCED_TYPENAME range_value<T>::type* fun(T& t)
{ {
return t; return t;
} }
@@ -71,7 +71,7 @@ namespace boost
namespace range_adl_barrier namespace range_adl_barrier
{ {
template< typename C > template< typename C >
inline BOOST_RANGE_DEDUCED_TYPENAME range_iterator<C>::type BOOST_CONSTEXPR inline BOOST_RANGE_DEDUCED_TYPENAME range_iterator<C>::type
begin( C& c ) begin( C& c )
{ {
return range_detail::range_begin< BOOST_RANGE_DEDUCED_TYPENAME range_detail::range<C>::type >::fun( c ); return range_detail::range_begin< BOOST_RANGE_DEDUCED_TYPENAME range_detail::range<C>::type >::fun( c );

View File

@@ -18,10 +18,8 @@
#include <boost/range/config.hpp> #include <boost/range/config.hpp>
#include <boost/range/detail/sfinae.hpp> #include <boost/range/detail/sfinae.hpp>
#include <boost/type_traits/is_void.hpp> #include <boost/type_traits/is_void.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/if.hpp> #include <boost/mpl/if.hpp>
#include <boost/mpl/int.hpp> #include <boost/mpl/int.hpp>
#include <boost/mpl/or.hpp>
#include <cstddef> #include <cstddef>
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
@@ -71,7 +69,7 @@ namespace boost
BOOST_STATIC_CONSTANT( bool, is_const_wchar_t_ptr_ = sizeof( boost::range_detail::is_const_wchar_t_ptr_impl( ptr ) ) == sizeof( yes_type ) ); BOOST_STATIC_CONSTANT( bool, is_const_wchar_t_ptr_ = sizeof( boost::range_detail::is_const_wchar_t_ptr_impl( ptr ) ) == sizeof( yes_type ) );
BOOST_STATIC_CONSTANT( bool, is_char_array_ = sizeof( boost::range_detail::is_char_array_impl( ptr ) ) == sizeof( yes_type ) ); BOOST_STATIC_CONSTANT( bool, is_char_array_ = sizeof( boost::range_detail::is_char_array_impl( ptr ) ) == sizeof( yes_type ) );
BOOST_STATIC_CONSTANT( bool, is_wchar_t_array_ = sizeof( boost::range_detail::is_wchar_t_array_impl( ptr ) ) == sizeof( yes_type ) ); BOOST_STATIC_CONSTANT( bool, is_wchar_t_array_ = sizeof( boost::range_detail::is_wchar_t_array_impl( ptr ) ) == sizeof( yes_type ) );
BOOST_STATIC_CONSTANT( bool, is_string_ = (boost::mpl::or_<boost::mpl::bool_<is_const_char_ptr_>, boost::mpl::bool_<is_const_wchar_t_ptr_> >::value )); BOOST_STATIC_CONSTANT( bool, is_string_ = (is_const_char_ptr_ || is_const_wchar_t_ptr_));
BOOST_STATIC_CONSTANT( bool, is_array_ = boost::is_array<C>::value ); BOOST_STATIC_CONSTANT( bool, is_array_ = boost::is_array<C>::value );
}; };

View File

@@ -32,6 +32,23 @@ public:
: m_impl(source) : m_impl(source)
{ {
} }
default_constructible_unary_fn_wrapper(const default_constructible_unary_fn_wrapper& source)
: m_impl(source.m_impl)
{
}
default_constructible_unary_fn_wrapper& operator=(const default_constructible_unary_fn_wrapper& source)
{
if (source.m_impl)
{
// Lambda are not copy/move assignable.
m_impl.emplace(*source.m_impl);
}
else
{
m_impl.reset();
}
return *this;
}
template<typename Arg> template<typename Arg>
R operator()(const Arg& arg) const R operator()(const Arg& arg) const
{ {

View File

@@ -33,7 +33,7 @@ namespace boost
struct range_end<std_container_> struct range_end<std_container_>
{ {
template< typename C > template< typename C >
static BOOST_RANGE_DEDUCED_TYPENAME range_iterator<C>::type BOOST_CONSTEXPR static BOOST_RANGE_DEDUCED_TYPENAME range_iterator<C>::type
fun( C& c ) fun( C& c )
{ {
return c.end(); return c.end();
@@ -48,7 +48,7 @@ namespace boost
struct range_end<std_pair_> struct range_end<std_pair_>
{ {
template< typename P > template< typename P >
static BOOST_RANGE_DEDUCED_TYPENAME range_iterator<P>::type BOOST_CONSTEXPR static BOOST_RANGE_DEDUCED_TYPENAME range_iterator<P>::type
fun( const P& p ) fun( const P& p )
{ {
return p.second; return p.second;
@@ -63,7 +63,7 @@ namespace boost
struct range_end<array_> struct range_end<array_>
{ {
template<typename T> template<typename T>
static BOOST_RANGE_DEDUCED_TYPENAME remove_extent<T>::type* fun(T& t) BOOST_CONSTEXPR static BOOST_RANGE_DEDUCED_TYPENAME remove_extent<T>::type* fun(T& t)
{ {
return t + remove_extent<T>::size; return t + remove_extent<T>::size;
} }
@@ -74,7 +74,7 @@ namespace boost
namespace range_adl_barrier namespace range_adl_barrier
{ {
template< typename C > template< typename C >
inline BOOST_RANGE_DEDUCED_TYPENAME range_iterator<C>::type BOOST_CONSTEXPR inline BOOST_RANGE_DEDUCED_TYPENAME range_iterator<C>::type
end( C& c ) end( C& c )
{ {
return range_detail::range_end< BOOST_RANGE_DEDUCED_TYPENAME range_detail::range<C>::type >::fun( c ); return range_detail::range_end< BOOST_RANGE_DEDUCED_TYPENAME range_detail::range<C>::type >::fun( c );

View File

@@ -60,13 +60,13 @@ namespace boost
} }
template< class T, std::size_t sz > template< class T, std::size_t sz >
inline T* array_end( T BOOST_RANGE_ARRAY_REF()[sz] ) BOOST_CONSTEXPR inline T* array_end( T BOOST_RANGE_ARRAY_REF()[sz] ) BOOST_NOEXCEPT
{ {
return boost_range_array + sz; return boost_range_array + sz;
} }
template< class T, std::size_t sz > template< class T, std::size_t sz >
inline const T* array_end( const T BOOST_RANGE_ARRAY_REF()[sz] ) BOOST_CONSTEXPR inline const T* array_end( const T BOOST_RANGE_ARRAY_REF()[sz] ) BOOST_NOEXCEPT
{ {
return boost_range_array + sz; return boost_range_array + sz;
} }

View File

@@ -153,8 +153,12 @@ template<typename Iterator1
typename iterator_reference<Iterator2>::type typename iterator_reference<Iterator2>::type
>::type >::type
>::value, >::value,
typename add_const< typename add_reference<
typename iterator_reference<Iterator1>::type typename add_const<
typename remove_reference<
typename iterator_reference<Iterator1>::type
>::type
>::type
>::type, >::type,
typename iterator_reference<Iterator1>::type typename iterator_reference<Iterator1>::type
>::type >::type

View File

@@ -15,18 +15,19 @@
# pragma once # pragma once
#endif #endif
#include <boost/iterator/distance.hpp>
#include <boost/range/begin.hpp> #include <boost/range/begin.hpp>
#include <boost/range/end.hpp> #include <boost/range/end.hpp>
#include <boost/range/difference_type.hpp> #include <boost/range/difference_type.hpp>
namespace boost namespace boost
{ {
template< class T > template< class T >
inline BOOST_DEDUCED_TYPENAME range_difference<T>::type inline BOOST_CXX14_CONSTEXPR BOOST_DEDUCED_TYPENAME range_difference<T>::type
distance( const T& r ) distance( const T& r )
{ {
return std::distance( boost::begin( r ), boost::end( r ) ); return boost::distance( boost::begin( r ), boost::end( r ) );
} }
} // namespace 'boost' } // namespace 'boost'

View File

@@ -37,7 +37,7 @@ namespace range_detail
// primary template // primary template
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
template< typename C > template< typename C >
inline BOOST_DEDUCED_TYPENAME range_iterator<C>::type BOOST_CONSTEXPR inline BOOST_DEDUCED_TYPENAME range_iterator<C>::type
range_end( C& c ) range_end( C& c )
{ {
// //
@@ -53,13 +53,13 @@ namespace range_detail
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
template< typename Iterator > template< typename Iterator >
inline Iterator range_end( const std::pair<Iterator,Iterator>& p ) BOOST_CONSTEXPR inline Iterator range_end( const std::pair<Iterator,Iterator>& p )
{ {
return p.second; return p.second;
} }
template< typename Iterator > template< typename Iterator >
inline Iterator range_end( std::pair<Iterator,Iterator>& p ) BOOST_CONSTEXPR inline Iterator range_end( std::pair<Iterator,Iterator>& p )
{ {
return p.second; return p.second;
} }
@@ -69,13 +69,13 @@ namespace range_detail
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
template< typename T, std::size_t sz > template< typename T, std::size_t sz >
inline const T* range_end( const T (&a)[sz] ) BOOST_CONSTEXPR inline const T* range_end( const T (&a)[sz] ) BOOST_NOEXCEPT
{ {
return range_detail::array_end<T,sz>( a ); return range_detail::array_end<T,sz>( a );
} }
template< typename T, std::size_t sz > template< typename T, std::size_t sz >
inline T* range_end( T (&a)[sz] ) BOOST_CONSTEXPR inline T* range_end( T (&a)[sz] ) BOOST_NOEXCEPT
{ {
return range_detail::array_end<T,sz>( a ); return range_detail::array_end<T,sz>( a );
} }
@@ -88,7 +88,7 @@ namespace range_adl_barrier
{ {
template< class T > template< class T >
inline BOOST_DEDUCED_TYPENAME range_iterator<T>::type end( T& r ) BOOST_CONSTEXPR inline BOOST_DEDUCED_TYPENAME range_iterator<T>::type end( T& r )
{ {
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
using namespace range_detail; using namespace range_detail;
@@ -97,7 +97,7 @@ inline BOOST_DEDUCED_TYPENAME range_iterator<T>::type end( T& r )
} }
template< class T > template< class T >
inline BOOST_DEDUCED_TYPENAME range_iterator<const T>::type end( const T& r ) BOOST_CONSTEXPR inline BOOST_DEDUCED_TYPENAME range_iterator<const T>::type end( const T& r )
{ {
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
using namespace range_detail; using namespace range_detail;
@@ -115,7 +115,7 @@ namespace boost
namespace range_adl_barrier namespace range_adl_barrier
{ {
template< class T > template< class T >
inline BOOST_DEDUCED_TYPENAME range_iterator<const T>::type BOOST_CONSTEXPR inline BOOST_DEDUCED_TYPENAME range_iterator<const T>::type
const_end( const T& r ) const_end( const T& r )
{ {
return boost::range_adl_barrier::end( r ); return boost::range_adl_barrier::end( r );

View File

@@ -37,9 +37,9 @@ namespace boost
T, T,
BOOST_DEDUCED_TYPENAME ::boost::enable_if< BOOST_DEDUCED_TYPENAME ::boost::enable_if<
BOOST_DEDUCED_TYPENAME mpl::eval_if<is_const<T>, BOOST_DEDUCED_TYPENAME mpl::eval_if<is_const<T>,
has_type<range_const_iterator< has_type<boost::range_const_iterator<
BOOST_DEDUCED_TYPENAME remove_const<T>::type> >, BOOST_DEDUCED_TYPENAME remove_const<T>::type> >,
has_type<range_mutable_iterator<T> > has_type<boost::range_mutable_iterator<T> >
>::type >::type
>::type >::type
> >
@@ -57,7 +57,7 @@ namespace boost
struct has_range_const_iterator_impl< struct has_range_const_iterator_impl<
T, T,
BOOST_DEDUCED_TYPENAME ::boost::enable_if< BOOST_DEDUCED_TYPENAME ::boost::enable_if<
has_type<range_const_iterator<T> > has_type<boost::range_const_iterator<T> >
>::type >::type
> >
: boost::mpl::true_ : boost::mpl::true_

View File

@@ -217,7 +217,7 @@ namespace boost
{ {
BOOST_ASSERT( step_size != 0 ); BOOST_ASSERT( step_size != 0 );
BOOST_ASSERT( (step_size > 0) ? (last >= first) : (last <= first) ); BOOST_ASSERT( (step_size > 0) ? (last >= first) : (last <= first) );
typedef typename range_detail::integer_iterator_with_step<Integer> iterator_t; typedef typename range_detail::integer_iterator_with_step<Integer> iterator_t;
const std::ptrdiff_t sz = static_cast<std::ptrdiff_t>(step_size >= 0 ? step_size : -step_size); const std::ptrdiff_t sz = static_cast<std::ptrdiff_t>(step_size >= 0 ? step_size : -step_size);
@@ -225,12 +225,19 @@ namespace boost
const Integer f = step_size >= 0 ? first : last; const Integer f = step_size >= 0 ? first : last;
const std::ptrdiff_t num_steps = (l - f) / sz + ((l - f) % sz ? 1 : 0); const std::ptrdiff_t num_steps = (l - f) / sz + ((l - f) % sz ? 1 : 0);
BOOST_ASSERT(num_steps >= 0); BOOST_ASSERT(num_steps >= 0);
return strided_integer_range<Integer>( return strided_integer_range<Integer>(
iterator_t(first, 0, step_size), iterator_t(first, 0, step_size),
iterator_t(first, num_steps, step_size)); iterator_t(first, num_steps, step_size));
} }
template<typename Integer>
integer_range<Integer>
irange(Integer last)
{
return integer_range<Integer>(static_cast<Integer>(0), last);
}
} // namespace boost } // namespace boost
#endif // include guard #endif // include guard

View File

@@ -59,6 +59,8 @@ test-suite range :
[ range-test adaptor_test/indexed ] [ range-test adaptor_test/indexed ]
[ range-test adaptor_test/indirected ] [ range-test adaptor_test/indirected ]
[ range-test adaptor_test/map ] [ range-test adaptor_test/map ]
[ range-test adaptor_test/ref_unwrapped ]
[ range-test adaptor_test/ref_unwrapped_example ]
[ range-test adaptor_test/replaced ] [ range-test adaptor_test/replaced ]
[ range-test adaptor_test/replaced_if ] [ range-test adaptor_test/replaced_if ]
[ range-test adaptor_test/reversed ] [ range-test adaptor_test/reversed ]

View File

@@ -51,6 +51,23 @@ namespace boost
bool operator()( IntegerT x ) const { return x % 2 != 0; } bool operator()( IntegerT x ) const { return x % 2 != 0; }
}; };
struct lambda_init
{
};
struct lambda
{
lambda(const lambda_init& init) {}
lambda(const lambda& rhs) {}
template< class T1 >
bool operator()(T1) const { return false; }
private:
lambda() {}
lambda& operator=(const lambda& rhs) { return *this; }
};
template< class Container, class Pred > template< class Container, class Pred >
void filtered_test_impl( Container& c, Pred pred ) void filtered_test_impl( Container& c, Pred pred )
{ {
@@ -86,32 +103,53 @@ namespace boost
test_result2.end() ); test_result2.end() );
} }
template< class Rng >
void check_copy_assign(Rng r)
{
Rng r2 = r;
r2 = r;
}
template< class Container, class Pred > template< class Container, class Pred >
void filtered_range_copy_assign(Container& c, Pred pred)
{
using namespace boost::adaptors;
check_copy_assign(c | filtered(pred));
check_copy_assign(adaptors::filter(c, pred));
}
template< class Container, class Pred, class PredInit >
void filtered_test_impl() void filtered_test_impl()
{ {
using namespace boost::assign; using namespace boost::assign;
Container c; Container c;
PredInit init;
Pred pred(init);
// test empty container // test empty container
filtered_test_impl(c, Pred()); filtered_test_impl(c, pred);
// test one element // test one element
c += 1; c += 1;
filtered_test_impl(c, Pred()); filtered_test_impl(c, pred);
// test many elements // test many elements
c += 1,2,2,2,3,4,4,4,4,5,6,7,8,9,9; c += 1,2,2,2,3,4,4,4,4,5,6,7,8,9,9;
filtered_test_impl(c, Pred()); filtered_test_impl(c, pred);
// test the range and iterator are copy assignable
filtered_range_copy_assign(c, pred);
} }
template< class Container > template< class Container >
void filtered_test_all_predicates() void filtered_test_all_predicates()
{ {
filtered_test_impl< Container, always_false_pred >(); filtered_test_impl< Container, always_false_pred, always_false_pred >();
filtered_test_impl< Container, always_true_pred >(); filtered_test_impl< Container, always_true_pred, always_true_pred >();
filtered_test_impl< Container, is_odd >(); filtered_test_impl< Container, is_odd, is_odd >();
filtered_test_impl< Container, is_even >(); filtered_test_impl< Container, is_even, is_even >();
filtered_test_impl< Container, lambda, lambda_init >();
} }
void ticket_10988_single_pass() void ticket_10988_single_pass()

View File

@@ -0,0 +1,101 @@
// Boost.Range library
//
// Copyright Robin Eckert 2015. 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 <boost/range/adaptor/ref_unwrapped.hpp>
#define BOOST_TEST_MAIN
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <vector>
#if !defined(BOOST_NO_CXX11_AUTO_DECLARATIONS) && !defined(BOOST_NO_CXX11_RANGE_BASED_FOR)
namespace boost
{
BOOST_AUTO_TEST_CASE(test_mutable)
{
int one = 1;
int two = 2;
int three = 3;
std::vector<std::reference_wrapper<int>> input_values{one, two, three};
const std::vector<int*> expected{&one, &two, &three};
std::vector<int*> actual;
for (auto&& value : input_values | adaptors::ref_unwrapped)
{
actual.push_back(&value);
}
BOOST_CHECK_EQUAL_COLLECTIONS(expected.begin(),
expected.end(),
actual.begin(),
actual.end());
}
BOOST_AUTO_TEST_CASE(test_const_range)
{
int one = 1;
int two = 2;
int three = 3;
const std::vector<std::reference_wrapper<int>> input_values{one, two, three};
const std::vector<int*> expected{&one, &two, &three};
std::vector<int*> actual;
for (auto&& value : input_values | adaptors::ref_unwrapped)
{
actual.push_back(&value);
}
BOOST_CHECK_EQUAL_COLLECTIONS(expected.begin(),
expected.end(),
actual.begin(),
actual.end());
}
BOOST_AUTO_TEST_CASE(test_const_reference)
{
const int one = 1;
const int two = 2;
const int three = 3;
const std::vector<std::reference_wrapper<const int>> input_values{one, two, three};
const std::vector<const int*> expected{&one, &two, &three};
std::vector<const int*> actual;
for (auto&& value : input_values | adaptors::ref_unwrapped)
{
actual.push_back(&value);
}
BOOST_CHECK_EQUAL_COLLECTIONS(expected.begin(),
expected.end(),
actual.begin(),
actual.end());
}
}
#else
BOOST_AUTO_TEST_CASE(empty)
{
// C++11 only
}
#endif

View File

@@ -0,0 +1,47 @@
// Boost.Range library
//
// Copyright Robin Eckert 2015. 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/
//
//[ref_unwrapped_example
#include <boost/range/adaptor/ref_unwrapped.hpp>
#include <iostream>
#include <vector>
struct example
{
int value;
};
int main(int argc, const char* argv[])
{
//<-
#if !defined(BOOST_NO_CXX11_DECLTYPE) \
&& !defined(BOOST_NO_CXX11_RANGE_BASED_FOR) \
&& !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) \
&& !defined(BOOST_NO_CXX11_AUTO_DECLARATIONS)
//->
using boost::adaptors::ref_unwrapped;
example one{1};
example two{2};
example three{3};
std::vector<std::reference_wrapper<example> > input{one, two, three};
for (auto&& entry : input | ref_unwrapped)
{
std::cout << entry.value;
}
return 0;
//<-
#endif
//->
}
//]

View File

@@ -9,7 +9,7 @@
// For more information, see http://www.boost.org/libs/range/ // For more information, see http://www.boost.org/libs/range/
// //
// The strided_defect_Trac5014 test case is a modified version of a test case // The strided_defect_Trac5014 test case is a modified version of a test case
// contributed by Michel Morin as part of the trac ticket. // contributed by Maxim Yanchenko as part of the trac ticket.
// //
// The deque test case has been removed due to erroneous standard library // The deque test case has been removed due to erroneous standard library
// implementations causing test failures. // implementations causing test failures.

View File

@@ -38,6 +38,24 @@ namespace boost
int operator()(int x) const { return x / 2; } int operator()(int x) const { return x / 2; }
}; };
struct lambda_init
{
};
struct lambda
{
typedef int result_type;
lambda(const lambda_init& init) {}
lambda(const lambda& rhs) {}
int operator()(int x) const { return x + 1; }
private:
lambda() {}
lambda& operator=(const lambda& rhs) { return *this; }
};
template< class Container, class TransformFn > template< class Container, class TransformFn >
void transformed_test_impl_core( Container& c, TransformFn fn ) void transformed_test_impl_core( Container& c, TransformFn fn )
{ {
@@ -59,13 +77,29 @@ namespace boost
test_result2.begin(), test_result2.end() ); test_result2.begin(), test_result2.end() );
} }
template< class Rng >
void check_copy_assign(Rng r)
{
Rng r2 = r;
r2 = r;
}
template< class Container, class TransformFn > template< class Container, class TransformFn >
void transformed_range_copy_assign(Container& c, TransformFn fn)
{
using namespace boost::adaptors;
check_copy_assign(c | transformed(fn));
check_copy_assign(adaptors::transform(c, fn));
}
template< class Container, class TransformFn, class TransformFnInit >
void transformed_test_fn_impl() void transformed_test_fn_impl()
{ {
using namespace boost::assign; using namespace boost::assign;
Container c; Container c;
TransformFn fn; TransformFnInit init;
TransformFn fn( init );
// Test empty // Test empty
transformed_test_impl_core(c, fn); transformed_test_impl_core(c, fn);
@@ -77,13 +111,17 @@ namespace boost
// Test many elements // Test many elements
c += 1,1,1,2,2,2,2,2,3,4,5,6,7,8,9; c += 1,1,1,2,2,2,2,2,3,4,5,6,7,8,9;
transformed_test_impl_core(c, fn); transformed_test_impl_core(c, fn);
// test the range and iterator are copy assignable
transformed_range_copy_assign(c, fn);
} }
template< class Container > template< class Container >
void transformed_test_impl() void transformed_test_impl()
{ {
transformed_test_fn_impl< Container, double_x >(); transformed_test_fn_impl< Container, double_x, double_x >();
transformed_test_fn_impl< Container, halve_x >(); transformed_test_fn_impl< Container, halve_x, halve_x >();
transformed_test_fn_impl< Container, lambda, lambda_init >();
} }
void transformed_test() void transformed_test()

View File

@@ -18,6 +18,23 @@
namespace boost namespace boost
{ {
// Test an integer range with a step size of 1.
template<typename Integer>
void test_irange_impl(Integer last)
{
std::vector<Integer> reference;
for (Integer i = static_cast<Integer>(0); i < last; ++i)
{
reference.push_back(i);
}
std::vector<Integer> test;
boost::push_back(test, boost::irange(last));
BOOST_CHECK_EQUAL_COLLECTIONS( test.begin(), test.end(),
reference.begin(), reference.end() );
}
// Test an integer range with a step size of 1. // Test an integer range with a step size of 1.
template<typename Integer> template<typename Integer>
void test_irange_impl(Integer first, Integer last) void test_irange_impl(Integer first, Integer last)
@@ -34,36 +51,52 @@ namespace boost
BOOST_CHECK_EQUAL_COLLECTIONS( test.begin(), test.end(), BOOST_CHECK_EQUAL_COLLECTIONS( test.begin(), test.end(),
reference.begin(), reference.end() ); reference.begin(), reference.end() );
} }
// Test an integer range with a runtime specified step size. // Test an integer range with a runtime specified step size.
template<typename Integer, typename IntegerInput> template<typename Integer, typename IntegerInput>
void test_irange_impl(IntegerInput first, IntegerInput last, int step) void test_irange_impl(IntegerInput first, IntegerInput last, int step)
{ {
BOOST_ASSERT( step != 0 ); BOOST_ASSERT( step != 0 );
// Skip tests that have negative values if the type is // Skip tests that have negative values if the type is
// unsigned // unsigned
if ((static_cast<IntegerInput>(static_cast<Integer>(first)) != first) if ((static_cast<IntegerInput>(static_cast<Integer>(first)) != first)
|| (static_cast<IntegerInput>(static_cast<Integer>(last)) != last)) || (static_cast<IntegerInput>(static_cast<Integer>(last)) != last))
return; return;
std::vector<Integer> reference; std::vector<Integer> reference;
const std::ptrdiff_t first_p = static_cast<std::ptrdiff_t>(first); const std::ptrdiff_t first_p = static_cast<std::ptrdiff_t>(first);
const std::ptrdiff_t last_p = static_cast<std::ptrdiff_t>(last); const std::ptrdiff_t last_p = static_cast<std::ptrdiff_t>(last);
const std::ptrdiff_t step_p = static_cast<std::ptrdiff_t>(step); const std::ptrdiff_t step_p = static_cast<std::ptrdiff_t>(step);
for (std::ptrdiff_t current_value = first_p; for (std::ptrdiff_t current_value = first_p;
step_p >= 0 ? current_value < last_p : current_value > last_p; step_p >= 0 ? current_value < last_p : current_value > last_p;
current_value += step_p) current_value += step_p)
reference.push_back(current_value); reference.push_back(current_value);
std::vector<Integer> test; std::vector<Integer> test;
boost::push_back(test, boost::irange(first, last, step)); boost::push_back(test, boost::irange(first, last, step));
BOOST_CHECK_EQUAL_COLLECTIONS( test.begin(), test.end(), BOOST_CHECK_EQUAL_COLLECTIONS( test.begin(), test.end(),
reference.begin(), reference.end() ); reference.begin(), reference.end() );
} }
// Test driver function that for an integer range [first, last)
// drives the test implementation through various integer
// types.
void test_irange(int last)
{
test_irange_impl<signed char>(last);
test_irange_impl<unsigned char>(last);
test_irange_impl<signed short>(last);
test_irange_impl<unsigned short>(last);
test_irange_impl<signed int>(last);
test_irange_impl<unsigned int>(last);
test_irange_impl<signed long>(last);
test_irange_impl<unsigned long>(last);
}
// Test driver function that for an integer range [first, last) // Test driver function that for an integer range [first, last)
// drives the test implementation through various integer // drives the test implementation through various integer
// types. // types.
@@ -102,6 +135,11 @@ namespace boost
// number of implementation branches. // number of implementation branches.
void irange_unit_test() void irange_unit_test()
{ {
// Test the single-step version of irange(last)
test_irange(0);
test_irange(1);
test_irange(10);
// Test the single-step version of irange(first, last) // Test the single-step version of irange(first, last)
test_irange(0, 0); test_irange(0, 0);
test_irange(0, 1); test_irange(0, 1);
@@ -124,14 +162,14 @@ namespace boost
test_irange(9, -9, -2); test_irange(9, -9, -2);
test_irange(10, 20, 5); test_irange(10, 20, 5);
test_irange(20, 10, -5); test_irange(20, 10, -5);
test_irange(0, 0, 3); test_irange(0, 0, 3);
test_irange(0, 1, 3); test_irange(0, 1, 3);
test_irange(0, 2, 3); test_irange(0, 2, 3);
test_irange(0, 3, 3); test_irange(0, 3, 3);
test_irange(0, 4, 3); test_irange(0, 4, 3);
test_irange(0, 10, 3); test_irange(0, 10, 3);
test_irange(0, 0, -3); test_irange(0, 0, -3);
test_irange(0, -1, -3); test_irange(0, -1, -3);
test_irange(0, -2, -3); test_irange(0, -2, -3);

View File

@@ -277,6 +277,7 @@ namespace boost
std::vector<int> v2; std::vector<int> v2;
std::vector<int> joined; std::vector<int> joined;
boost::push_back(joined, join(v1, v2)); boost::push_back(joined, join(v1, v2));
boost::push_back(joined, join(v2, v1));
} }
namespace trac7376 namespace trac7376

View File

@@ -14,7 +14,6 @@
#include <boost/test/test_tools.hpp> #include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp> #include <boost/test/unit_test.hpp>
#include <functional>
#include <vector> #include <vector>
namespace boost namespace boost
@@ -22,9 +21,12 @@ namespace boost
namespace namespace
{ {
class TestTicket5486Pred class TestTicket5486Pred
: public std::binary_function<int,int,bool>
{ {
public: public:
typedef int first_argument_type;
typedef int second_argument_type;
typedef bool result_type;
explicit TestTicket5486Pred(int x) {} explicit TestTicket5486Pred(int x) {}
bool operator()(int,int) const { return true; } bool operator()(int,int) const { return true; }
private: private: