Performance improvement: Add move semantics to by-value parameters (iterator and predicate), to eliminate the cost of copy-construction. Both the Predicate (Normally a std::function, or lambda), and custom iterators can have state, which can be expensive to copy. Profiler identified this as a bottleneck while using boost::adaptors::filtered.
The MPL version is slower to compile and `BOOST_STATIC_ASSERT` is
already used in some places. So unify that.
This also fixes `Wzero-as-null-pointer-constant` warnings, see https://github.com/boostorg/mpl/pull/75
The recent commit 5777e9944b broke code such as
(*it++).foo(), where the result of dereferencing would be convertible to
the value type but did not provide the members of the value type. To mitigate
this, return a reference to the value instead of a proxy object. This will only
work for non-writable iterators (and it didn't work for writable iterators
before either) because in that case a proxy is needed to be able to intercept
operator=.
Also fix a similar issue with (it++)->foo() by adding operator-> overloads
to the post-increment result proxies.
Added tests for the fixes.
This allows expressions such as `Iterator it2(it1++)` to compile.
Additionally separated operations that are allowed on the result of
dereferencing the proxy to a separate set of proxies to make the allowed
set of expressions more strict and unambiguous. In particular, it means
`it++` cannot be converted to value type and `*it++` cannot be converted
to the iterator type anymore. Also, make sure `*it1++ = *it2++` works
as expexted by explicitly converting the proxy to the value type on
assignment.
Fixes https://github.com/boostorg/iterator/issues/75.
This fixes incorrect final iterator type being used in iterator_facade, which
results in an internal base class being returned from various facade methods.
Reported in https://github.com/boostorg/iterator/issues/75.
This should silence gcc warnings about deprecated implicit copy assignment
operator because of the explicitly defined copy constructor. Also, changed
constructor definitions to be defaulted when possible and added missing
includes.
Closes https://github.com/boostorg/iterator/pull/69.
Boost's iterator.hpp is deprecated, too. Therefore get rid of all of that and replace inheritance by lifting std::iterator's members into the derived class.
Signed-off-by: Daniela Engert <dani@ngrt.de>
Regardless of value categories of a transform_iterator object, its
dereference operator calls m_f as an lvalue. Thus, correct usage of
decltype-based result_of is result_of<const UnaryFunc&(...)>.
Both make_function_input_iterator(function) and make...(&function)
do not depend on function_reference_input_iterator. Actually, passing a
function reference as a template argument to function_input_iterator is
not supported. Doing so results in compiler errors.
By using Boost.Iterator we rely on the separate traversal category instead of
the standard iterator category to advance iterators efficiently. For instance,
this allows to advance transform iterators over a random access sequence
in constant time, despite that they are formally input iterators.
Also, std::reverse_iterator formally requires at least bidirectional iterator
as the underlying iterator type. Transform iterators from the example above
don't qualify, so potentially std::reverse_iterator could fail to compile.
The new implementation tries to detect if the incremented/decremented type
is an iterator first and if not falls back to operator probing. This way
iterators that are not SFINAE-friendly (i.e. unconditionally define
arithmetic operators regardless of the iterator category) are still treated
as iterators through std::advance and do not fail the compilation.
The iterator detection is based on probing for the nested iterator_category
type that is expected to be present in class-type iterators. This heuristic
is not flawless since iterators are not required to defined this type.
User-defined iterators may not have it and instead specialize
std::iterator_traits. This use case is not covered by the current implementation
and will likely fail to compile. With C++17 SFINAE-friendly std::iterator_traits
this can be fixed, but currently Boost.Config lacks the macro to detect
availability of this feature. Support for it can be added by a later commit.
Also simplified boost::prior for iterators, removing the possibility of
integer overflow caused by negation of the distance value.