init
Some checks failed
Docker. / Ubuntu (push) Has been cancelled
User-agent updater. / User-agent (push) Failing after 15s
Lock Threads / lock (push) Failing after 10s
Waiting for answer. / waiting-for-answer (push) Failing after 22s
Needs user action. / needs-user-action (push) Failing after 8s
Can't reproduce. / cant-reproduce (push) Failing after 8s
Close stale issues and PRs / stale (push) Has been cancelled

This commit is contained in:
allhaileris
2026-02-16 15:50:16 +03:00
commit afb81b8278
13816 changed files with 3689732 additions and 0 deletions

View File

@@ -0,0 +1,247 @@
/// \file
// Range v3 library
//
// Copyright Eric Niebler 2013-present
//
// 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)
//
// Project home: https://github.com/ericniebler/range-v3
//
#ifndef RANGES_V3_CONTAINER_ACTION_HPP
#define RANGES_V3_CONTAINER_ACTION_HPP
#include <type_traits>
#include <meta/meta.hpp>
#include <range/v3/range_fwd.hpp>
#include <range/v3/action/concepts.hpp>
#include <range/v3/functional/compose.hpp>
#include <range/v3/functional/concepts.hpp>
#include <range/v3/functional/invoke.hpp>
#include <range/v3/functional/reference_wrapper.hpp>
#include <range/v3/functional/pipeable.hpp>
#include <range/v3/range/concepts.hpp>
#include <range/v3/utility/move.hpp>
#include <range/v3/utility/static_const.hpp>
#include <range/v3/detail/prologue.hpp>
namespace ranges
{
/// \addtogroup group-actions
/// @{
struct make_action_closure_fn
{
template<typename Fun>
constexpr actions::action_closure<Fun> operator()(Fun fun) const
{
return actions::action_closure<Fun>{static_cast<Fun &&>(fun)};
}
};
/// \sa make_action_closure_fn
RANGES_INLINE_VARIABLE(make_action_closure_fn, make_action_closure)
/// \cond
namespace detail
{
struct action_closure_base_
{};
}
/// \endcond
/// \concept invocable_action_closure_
/// \brief The \c invocable_action_closure_ concept
template(typename ActionFn, typename Rng)(
concept (invocable_action_closure_)(ActionFn, Rng),
!derived_from<invoke_result_t<ActionFn, Rng>, detail::action_closure_base_>
);
/// \concept invocable_action_closure
/// \brief The \c invocable_action_closure concept
template<typename ActionFn, typename Rng>
CPP_concept invocable_action_closure =
invocable<ActionFn, Rng> &&
CPP_concept_ref(ranges::invocable_action_closure_, ActionFn, Rng);
namespace actions
{
struct RANGES_STRUCT_WITH_ADL_BARRIER(action_closure_base)
: detail::action_closure_base_
{
// clang-format off
// Piping requires things are passed by value.
template(typename Rng, typename ActionFn)(
requires (!std::is_lvalue_reference<Rng>::value) AND
range<Rng> AND invocable_action_closure<ActionFn, Rng &>)
friend constexpr auto
operator|(Rng && rng, action_closure<ActionFn> act)
{
return aux::move(static_cast<ActionFn &&>(act)(rng));
}
#ifndef RANGES_WORKAROUND_CLANG_43400
template<typename Rng, typename ActionFn> // ******************************
friend constexpr auto // ******************************
operator|(Rng &, // ********* READ THIS **********
action_closure<ActionFn> const &) // ****** IF YOUR COMPILE *******
-> CPP_broken_friend_ret(Rng)( // ******** BREAKS HERE *********
requires range<Rng>) = delete; // ******************************
// **************************************************************************
// * When piping a range into an action, the range must be moved in. *
// **************************************************************************
#endif // RANGES_WORKAROUND_CLANG_43400
template<typename ActionFn, typename Pipeable>
friend constexpr auto operator|(action_closure<ActionFn> act, Pipeable pipe)
-> CPP_broken_friend_ret(action_closure<composed<Pipeable, ActionFn>>)(
requires (is_pipeable_v<Pipeable>))
{
return make_action_closure(compose(static_cast<Pipeable &&>(pipe),
static_cast<ActionFn &&>(act)));
}
template<typename Rng, typename ActionFn>
friend constexpr auto operator|=(Rng & rng, action_closure<ActionFn> act) //
-> CPP_broken_friend_ret(Rng &)(
requires range<Rng> && invocable<ActionFn, Rng &>)
{
static_cast<ActionFn &&>(act)(rng);
return rng;
}
// clang-format on
};
#ifdef RANGES_WORKAROUND_CLANG_43400
// clang-format off
namespace RANGES_ADL_BARRIER_FOR(action_closure_base)
{
template(typename Rng, typename ActionFn)( // *******************************
requires range<Rng>) // *******************************
constexpr Rng // ********** READ THIS **********
operator|(Rng &, // ******* IF YOUR COMPILE *******
action_closure<ActionFn> const &) // ********* BREAKS HERE *********
= delete; // *******************************
// ***************************************************************************
// * When piping a range into an action, the range must be moved in. *
// ***************************************************************************
} // namespace RANGES_ADL_BARRIER_FOR(action_closure_base)
// clang-format on
#endif // RANGES_WORKAROUND_CLANG_43400
template<typename ActionFn>
struct RANGES_EMPTY_BASES action_closure
: action_closure_base
, ActionFn
{
action_closure() = default;
constexpr explicit action_closure(ActionFn fn)
: ActionFn(static_cast<ActionFn &&>(fn))
{}
};
/// \cond
/// DEPRECATED STUFF
struct action_access_
{
template<typename Action>
struct impl
{
// clang-format off
template<typename... Ts, typename A = Action>
static constexpr auto CPP_auto_fun(bind)(Ts &&... ts)
(
return A::bind(static_cast<Ts &&>(ts)...)
)
// clang-format on
};
};
using action_access RANGES_DEPRECATED(
"action_access and actions::action<> are deprecated. Please "
"replace action<> with action_closure<> and discontinue use of "
"action_access.") = action_access_;
template<typename>
struct old_action_;
struct make_action_fn_
{
template<typename Fun>
constexpr old_action_<Fun> operator()(Fun fun) const
{
return old_action_<Fun>{static_cast<Fun &&>(fun)};
}
};
using make_action_fn RANGES_DEPRECATED(
"make_action_fn is deprecated. Please use "
"make_action_closure instead.") = make_action_fn_;
namespace
{
RANGES_DEPRECATED(
"make_action and actions::action<> has been deprecated. Please switch to "
"make_action_closure and action::action_closure.")
RANGES_INLINE_VAR constexpr auto & make_action =
static_const<make_action_fn_>::value;
} // namespace
template<typename Action>
struct old_action_ : pipeable_base
{
private:
Action act_;
friend pipeable_access;
public:
old_action_() = default;
constexpr explicit old_action_(Action a) noexcept(
std::is_nothrow_move_constructible<Action>::value)
: act_(detail::move(a))
{}
// Calling directly requires things are passed by reference.
template(typename Rng, typename... Rest)(
requires range<Rng> AND invocable<Action const &, Rng &, Rest...>)
invoke_result_t<Action const &, Rng &, Rest...> //
operator()(Rng & rng, Rest &&... rest) const
{
return invoke(act_, rng, static_cast<Rest &&>(rest)...);
}
// Currying overload.
// clang-format off
template(typename... Rest, typename A = Action)(
requires (sizeof...(Rest) != 0))
auto CPP_auto_fun(operator())(Rest &&... rest)(const)
(
return make_action_fn_{}(
action_access_::impl<A>::bind(act_,
static_cast<Rest &&>(rest)...))
)
// clang-format on
};
template<typename Action>
using action RANGES_DEPRECATED(
"The actions::action<> template is deprecated. Please switch to "
"action_closure") = old_action_<Action>;
/// \endcond
} // namespace actions
template<typename ActionFn>
RANGES_INLINE_VAR constexpr bool is_pipeable_v<actions::action_closure<ActionFn>> =
true;
/// @}
} // namespace ranges
#include <range/v3/detail/epilogue.hpp>
#endif

View File

@@ -0,0 +1,68 @@
/// \file
// Range v3 library
//
// Copyright Eric Niebler
// Copyright Christopher Di Bella
//
// 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)
//
// Project home: https://github.com/ericniebler/range-v3
//
#ifndef RANGES_V3_ACTION_ADJACENT_REMOVE_IF_HPP
#define RANGES_V3_ACTION_ADJACENT_REMOVE_IF_HPP
#include <utility>
#include <range/v3/range_fwd.hpp>
#include <range/v3/action/action.hpp>
#include <range/v3/action/erase.hpp>
#include <range/v3/algorithm/adjacent_remove_if.hpp>
#include <range/v3/functional/bind_back.hpp>
#include <range/v3/functional/identity.hpp>
#include <range/v3/range/traits.hpp>
#include <range/v3/utility/static_const.hpp>
#include <range/v3/detail/prologue.hpp>
namespace ranges
{
/// \addtogroup group-actions
/// @{
namespace actions
{
struct adjacent_remove_if_fn
{
template(typename Pred, typename Proj = identity)(
requires (!range<Pred>))
constexpr auto operator()(Pred pred, Proj proj = {}) const
{
return make_action_closure(
bind_back(adjacent_remove_if_fn{}, std::move(pred), std::move(proj)));
}
template(typename Rng, typename Pred, typename Proj = identity)(
requires forward_range<Rng> AND
erasable_range<Rng, iterator_t<Rng>, sentinel_t<Rng>> AND
indirect_relation<Pred, projected<iterator_t<Rng>, Proj>> AND
permutable<iterator_t<Rng>>)
Rng operator()(Rng && rng, Pred pred, Proj proj = {}) const
{
auto i = adjacent_remove_if(rng, std::move(pred), std::move(proj));
erase(rng, std::move(i), end(rng));
return static_cast<Rng &&>(rng);
}
};
/// \relates actions::adjacent_remove_if_fn
RANGES_INLINE_VARIABLE(adjacent_remove_if_fn, adjacent_remove_if)
} // namespace actions
/// @}
} // namespace ranges
#include <range/v3/detail/epilogue.hpp>
#endif // RANGES_V3_ACTION_ADJACENT_REMOVE_IF_HPP

View File

@@ -0,0 +1,185 @@
/// \file
// Range v3 library
//
// Copyright Eric Niebler 2013-present
//
// 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)
//
// Project home: https://github.com/ericniebler/range-v3
//
#ifndef RANGES_V3_ACTION_CONCEPTS_HPP
#define RANGES_V3_ACTION_CONCEPTS_HPP
#include <utility>
#include <meta/meta.hpp>
#include <range/v3/range_fwd.hpp>
#include <range/v3/range/concepts.hpp>
#include <range/v3/range/traits.hpp>
#include <range/v3/detail/prologue.hpp>
namespace ranges
{
/// \cond
namespace detail
{
template<typename T>
struct movable_input_iterator
{
using iterator_category = std::input_iterator_tag;
using value_type = T;
using difference_type = std::ptrdiff_t;
using pointer = T *;
using reference = T &&;
movable_input_iterator() = default;
movable_input_iterator & operator++();
movable_input_iterator operator++(int);
bool operator==(movable_input_iterator const &) const;
bool operator!=(movable_input_iterator const &) const;
T && operator*() const;
};
} // namespace detail
/// \endcond
/// \addtogroup group-range
/// @{
// clang-format off
/// \concept semi_container
/// \brief The \c semi_container concept
/// \c std::array is a \c semi_container, native arrays are not.
template<typename T>
CPP_concept semi_container =
forward_range<T> && default_constructible<uncvref_t<T>> &&
movable<uncvref_t<T>> &&
!view_<T>;
/// \concept container_
/// \brief The \c container_ concept
/// \c std::vector is a container, \c std::array is not
template(typename T)(
concept (container_)(T),
constructible_from<
uncvref_t<T>,
detail::movable_input_iterator<range_value_t<T>>,
detail::movable_input_iterator<range_value_t<T>>>
);
/// \concept container
/// \brief The \c container concept
template<typename T>
CPP_concept container =
semi_container<T> &&
CPP_concept_ref(ranges::container_, T);
/// \concept reservable_
/// \brief The \c reservable_ concept
template<typename C>
CPP_requires(reservable_,
requires(C & c, C const & cc) //
(
c.reserve(ranges::size(c)),
cc.capacity(),
cc.max_size(),
concepts::requires_<same_as<decltype(cc.capacity()),
decltype(ranges::size(c))>>,
concepts::requires_<same_as<decltype(cc.max_size()),
decltype(ranges::size(c))>>
));
/// \concept reservable
/// \brief The \c reservable concept
template<typename C>
CPP_concept reservable =
container<C> && sized_range<C> && CPP_requires_ref(ranges::reservable_, C);
/// \concept reservable_with_assign_
/// \brief The \c reservable_with_assign_ concept
template<typename C, typename I>
CPP_requires(reservable_with_assign_,
requires(C & c, I i) //
(
c.assign(i, i)
));
/// \concept reservable_with_assign
/// \brief The \c reservable_with_assign concept
template<typename C, typename I>
CPP_concept reservable_with_assign =
reservable<C> && //
input_iterator<I> && //
CPP_requires_ref(ranges::reservable_with_assign_, C, I);
/// \concept random_access_reservable
/// \brief The \c random_access_reservable concept
template<typename C>
CPP_concept random_access_reservable =
reservable<C> && random_access_range<C>;
// clang-format on
/// \cond
namespace detail
{
template(typename T)(
requires container<T>)
std::true_type is_lvalue_container_like(T &) noexcept
{
return {};
}
template(typename T)(
requires container<T>)
meta::not_<std::is_rvalue_reference<T>> //
is_lvalue_container_like(reference_wrapper<T>) noexcept
{
return {};
}
template(typename T)(
requires container<T>)
std::true_type is_lvalue_container_like(std::reference_wrapper<T>) noexcept
{
return {};
}
template(typename T)(
requires container<T>)
std::true_type is_lvalue_container_like(ref_view<T>) noexcept
{
return {};
}
template<typename T>
using is_lvalue_container_like_t =
decltype(detail::is_lvalue_container_like(std::declval<T>()));
} // namespace detail
/// \endcond
// clang-format off
/// \concept lvalue_container_like_
/// \brief The \c lvalue_container_like_ concept
template(typename T)(
concept (lvalue_container_like_)(T),
implicitly_convertible_to<detail::is_lvalue_container_like_t<T>, std::true_type>
);
/// \concept lvalue_container_like
/// \brief The \c lvalue_container_like concept
template<typename T>
CPP_concept lvalue_container_like =
forward_range<T> &&
CPP_concept_ref(ranges::lvalue_container_like_, T);
// clang-format on
/// @}
} // namespace ranges
#include <range/v3/detail/epilogue.hpp>
#endif

View File

@@ -0,0 +1,65 @@
/// \file
// Range v3 library
//
// Copyright Eric Niebler 2013-present
//
// 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)
//
// Project home: https://github.com/ericniebler/range-v3
//
#ifndef RANGES_V3_ACTION_DROP_HPP
#define RANGES_V3_ACTION_DROP_HPP
#include <range/v3/range_fwd.hpp>
#include <range/v3/action/action.hpp>
#include <range/v3/action/erase.hpp>
#include <range/v3/functional/bind_back.hpp>
#include <range/v3/iterator/concepts.hpp>
#include <range/v3/iterator/operations.hpp>
#include <range/v3/iterator/traits.hpp>
#include <range/v3/utility/static_const.hpp>
#include <range/v3/detail/prologue.hpp>
namespace ranges
{
/// \addtogroup group-actions
/// @{
namespace actions
{
struct drop_fn
{
template(typename Int)(
requires detail::integer_like_<Int>)
constexpr auto operator()(Int n) const
{
RANGES_EXPECT(n >= Int(0));
return make_action_closure(bind_back(drop_fn{}, n));
}
template(typename Rng)(
requires forward_range<Rng> AND
erasable_range<Rng &, iterator_t<Rng>, iterator_t<Rng>>)
Rng operator()(Rng && rng, range_difference_t<Rng> n) const
{
RANGES_EXPECT(n >= 0);
ranges::actions::erase(
rng, begin(rng), ranges::next(begin(rng), n, end(rng)));
return static_cast<Rng &&>(rng);
}
};
/// \relates actions::drop_fn
RANGES_INLINE_VARIABLE(drop_fn, drop)
} // namespace actions
/// @}
} // namespace ranges
#include <range/v3/detail/epilogue.hpp>
#endif

View File

@@ -0,0 +1,64 @@
/// \file
// Range v3 library
//
// Copyright Eric Niebler 2013-present
//
// 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)
//
// Project home: https://github.com/ericniebler/range-v3
//
#ifndef RANGES_V3_ACTION_DROP_WHILE_HPP
#define RANGES_V3_ACTION_DROP_WHILE_HPP
#include <range/v3/range_fwd.hpp>
#include <range/v3/action/action.hpp>
#include <range/v3/action/erase.hpp>
#include <range/v3/algorithm/find_if_not.hpp>
#include <range/v3/functional/bind_back.hpp>
#include <range/v3/iterator/concepts.hpp>
#include <range/v3/iterator/traits.hpp>
#include <range/v3/utility/static_const.hpp>
#include <range/v3/detail/prologue.hpp>
namespace ranges
{
/// \addtogroup group-actions
/// @{
namespace actions
{
struct drop_while_fn
{
template(typename Fun)(
requires (!range<Fun>))
constexpr auto operator()(Fun fun) const
{
return make_action_closure(bind_back(drop_while_fn{}, std::move(fun)));
}
template(typename Rng, typename Fun)(
requires forward_range<Rng> AND
indirect_unary_predicate<Fun, iterator_t<Rng>> AND
erasable_range<Rng &, iterator_t<Rng>, iterator_t<Rng>>)
Rng operator()(Rng && rng, Fun fun) const
{
ranges::actions::erase(
rng, begin(rng), find_if_not(begin(rng), end(rng), std::move(fun)));
return static_cast<Rng &&>(rng);
}
};
/// \relates actions::drop_while_fn
RANGES_INLINE_VARIABLE(drop_while_fn, drop_while)
} // namespace actions
/// @}
} // namespace ranges
#include <range/v3/detail/epilogue.hpp>
#endif

View File

@@ -0,0 +1,84 @@
/// \file
// Range v3 library
//
// Copyright Eric Niebler 2013-present
//
// 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)
//
// Project home: https://github.com/ericniebler/range-v3
//
#ifndef RANGES_V3_ACTION_ERASE_HPP
#define RANGES_V3_ACTION_ERASE_HPP
#include <utility>
#include <range/v3/range_fwd.hpp>
#include <range/v3/action/insert.hpp>
#include <range/v3/utility/static_const.hpp>
#include <range/v3/detail/prologue.hpp>
namespace ranges
{
/// \cond
namespace adl_erase_detail
{
template(typename Cont, typename I, typename S)(
requires lvalue_container_like<Cont> AND forward_iterator<I> AND
sentinel_for<S, I>)
auto erase(Cont && cont, I first, S last) //
-> decltype(unwrap_reference(cont).erase(first, last))
{
return unwrap_reference(cont).erase(first, last);
}
struct erase_fn
{
template(typename Rng, typename I, typename S)(
requires range<Rng> AND forward_iterator<I> AND sentinel_for<S, I>)
auto operator()(Rng && rng, I first, S last) const
-> decltype(erase((Rng &&) rng, first, last))
{
return erase(static_cast<Rng &&>(rng), first, last);
}
};
} // namespace adl_erase_detail
/// \endcond
/// \ingroup group-actions
RANGES_INLINE_VARIABLE(adl_erase_detail::erase_fn, erase)
namespace actions
{
using ranges::erase;
}
/// \addtogroup group-range
/// @{
// clang-format off
/// \concept erasable_range_
/// \brief The \c erasable_range_ concept
template<typename Rng, typename I, typename S>
CPP_requires(erasable_range_,
requires(Rng && rng, I first, S last)
(
ranges::erase((Rng &&) rng, first, last)
)
);
/// \concept erasable_range
/// \brief The \c erasable_range concept
template<typename Rng, typename I, typename S>
CPP_concept erasable_range =
range<Rng> && CPP_requires_ref(ranges::erasable_range_, Rng, I, S);
// clang-format on
/// @}
} // namespace ranges
#include <range/v3/detail/epilogue.hpp>
#endif

View File

@@ -0,0 +1,299 @@
/// \file
// Range v3 library
//
// Copyright Eric Niebler 2013-present
//
// 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)
//
// Project home: https://github.com/ericniebler/range-v3
//
#ifndef RANGES_V3_ACTION_INSERT_HPP
#define RANGES_V3_ACTION_INSERT_HPP
#include <initializer_list>
#include <utility>
#include <range/v3/range_fwd.hpp>
#include <range/v3/action/concepts.hpp>
#include <range/v3/algorithm/max.hpp>
#include <range/v3/iterator/common_iterator.hpp>
#include <range/v3/range/traits.hpp>
#include <range/v3/utility/static_const.hpp>
#include <range/v3/detail/prologue.hpp>
namespace ranges
{
/// \cond
namespace adl_insert_detail
{
template<typename Cont, typename... Args>
using insert_result_t = decltype(
unwrap_reference(std::declval<Cont>()).insert(std::declval<Args>()...));
template(typename Cont, typename T)(
requires lvalue_container_like<Cont> AND
(!range<T> && constructible_from<range_value_t<Cont>, T>)) //
insert_result_t<Cont &, T> insert(Cont && cont, T && t)
{
return unwrap_reference(cont).insert(static_cast<T &&>(t));
}
template(typename Cont, typename I, typename S)(
requires lvalue_container_like<Cont> AND sentinel_for<S, I> AND (!range<S>))
insert_result_t<Cont &, detail::cpp17_iterator_t<I, S>,
detail::cpp17_iterator_t<I, S>>
insert(Cont && cont, I i, S j)
{
return unwrap_reference(cont).insert(detail::cpp17_iterator_t<I, S>{i},
detail::cpp17_iterator_t<I, S>{j});
}
template(typename Cont, typename Rng)(
requires lvalue_container_like<Cont> AND range<Rng>)
insert_result_t<Cont &, detail::range_cpp17_iterator_t<Rng>,
detail::range_cpp17_iterator_t<Rng>>
insert(Cont && cont, Rng && rng)
{
return unwrap_reference(cont).insert(
detail::range_cpp17_iterator_t<Rng>{ranges::begin(rng)},
detail::range_cpp17_iterator_t<Rng>{ranges::end(rng)});
}
template(typename Cont, typename I, typename T)(
requires lvalue_container_like<Cont> AND input_iterator<I> AND
(!range<T> && constructible_from<range_value_t<Cont>, T>)) //
insert_result_t<Cont &, I, T> insert(Cont && cont, I p, T && t)
{
return unwrap_reference(cont).insert(p, static_cast<T &&>(t));
}
template(typename Cont, typename I, typename N, typename T)(
requires lvalue_container_like<Cont> AND input_iterator<I> AND
integral<N> AND constructible_from<range_value_t<Cont>, T>)
insert_result_t<Cont &, I, N, T> insert(Cont && cont, I p, N n, T && t)
{
return unwrap_reference(cont).insert(p, n, static_cast<T &&>(t));
}
/// \cond
namespace detail
{
using ranges::detail::cpp17_iterator_t;
using ranges::detail::range_cpp17_iterator_t;
template(typename Cont, typename P)(
requires container<Cont> AND input_iterator<P> AND
random_access_reservable<Cont>)
iterator_t<Cont> insert_reserve_helper(
Cont & cont, P const p, range_size_t<Cont> const delta)
{
auto const old_size = ranges::size(cont);
auto const max_size = cont.max_size();
RANGES_EXPECT(delta <= max_size - old_size);
auto const new_size = old_size + delta;
auto const old_capacity = cont.capacity();
auto const index = p - ranges::begin(cont);
if(old_capacity < new_size)
{
auto const new_capacity =
(old_capacity <= max_size / 3 * 2)
? ranges::max(old_capacity + old_capacity / 2, new_size)
: max_size;
cont.reserve(new_capacity);
}
return ranges::begin(cont) + index;
}
template(typename Cont, typename P, typename I, typename S)(
requires sentinel_for<S, I> AND (!range<S>)) //
auto insert_impl(Cont && cont, P p, I i, S j, std::false_type)
-> decltype(unwrap_reference(cont).insert(
p, cpp17_iterator_t<I, S>{i}, cpp17_iterator_t<I, S>{j}))
{
using C = cpp17_iterator_t<I, S>;
return unwrap_reference(cont).insert(p, C{i}, C{j});
}
template(typename Cont, typename P, typename I, typename S)(
requires sized_sentinel_for<S, I> AND random_access_reservable<Cont> AND
(!range<S>)) //
auto insert_impl(Cont && cont_, P p, I i, S j, std::true_type)
-> decltype(unwrap_reference(cont_).insert(
ranges::begin(unwrap_reference(cont_)), cpp17_iterator_t<I, S>{i},
cpp17_iterator_t<I, S>{j}))
{
using C = cpp17_iterator_t<I, S>;
auto && cont = unwrap_reference(cont_);
auto const delta = static_cast<range_size_t<Cont>>(j - i);
auto pos = insert_reserve_helper(cont, std::move(p), delta);
return cont.insert(pos, C{std::move(i)}, C{std::move(j)});
}
template(typename Cont, typename I, typename Rng)(
requires range<Rng>)
auto insert_impl(Cont && cont, I p, Rng && rng, std::false_type)
-> decltype(unwrap_reference(cont).insert(
p, range_cpp17_iterator_t<Rng>{ranges::begin(rng)},
range_cpp17_iterator_t<Rng>{ranges::end(rng)}))
{
using C = range_cpp17_iterator_t<Rng>;
return unwrap_reference(cont).insert(
p, C{ranges::begin(rng)}, C{ranges::end(rng)});
}
template(typename Cont, typename I, typename Rng)(
requires random_access_reservable<Cont> AND sized_range<Rng>)
auto insert_impl(Cont && cont_, I p, Rng && rng, std::true_type)
-> decltype(unwrap_reference(cont_).insert(
begin(unwrap_reference(cont_)),
range_cpp17_iterator_t<Rng>{ranges::begin(rng)},
range_cpp17_iterator_t<Rng>{ranges::end(rng)}))
{
using C = range_cpp17_iterator_t<Rng>;
auto && cont = unwrap_reference(cont_);
auto const delta = static_cast<range_size_t<Cont>>(ranges::size(rng));
auto pos = insert_reserve_helper(cont, std::move(p), delta);
return cont.insert(pos, C{ranges::begin(rng)}, C{ranges::end(rng)});
}
} // namespace detail
/// \endcond
template(typename Cont, typename P, typename I, typename S)(
requires lvalue_container_like<Cont> AND input_iterator<P> AND
sentinel_for<S, I> AND
(!range<S>)) //
auto insert(Cont && cont, P p, I i, S j) //
-> decltype(detail::insert_impl(
static_cast<Cont &&>(cont),
static_cast<P &&>(p),
static_cast<I &&>(i),
static_cast<S &&>(j),
meta::bool_<random_access_reservable<Cont> && //
sized_sentinel_for<S, I>>{}))
{
return detail::insert_impl(static_cast<Cont &&>(cont),
static_cast<P &&>(p),
static_cast<I &&>(i),
static_cast<S &&>(j),
meta::bool_<random_access_reservable<Cont> &&
sized_sentinel_for<S, I>>{});
}
template(typename Cont, typename I, typename Rng)(
requires lvalue_container_like<Cont> AND input_iterator<I> AND range<Rng>)
auto insert(Cont && cont, I p, Rng && rng)
-> decltype(detail::insert_impl(
static_cast<Cont &&>(cont), std::move(p), static_cast<Rng &&>(rng),
meta::bool_<random_access_reservable<Cont> && sized_range<Rng>>{}))
{
return detail::insert_impl(static_cast<Cont &&>(cont),
std::move(p),
static_cast<Rng &&>(rng),
meta::bool_<random_access_reservable<Cont> &&
sized_range<Rng>>{});
}
struct insert_fn
{
template<typename Rng, typename... Args>
using insert_result_t =
decltype(insert(std::declval<Rng>(), std::declval<Args>()...));
template(typename Rng, typename T)(
requires range<Rng> AND
(!range<T>) AND constructible_from<range_value_t<Rng>, T>)
insert_result_t<Rng, T> operator()(Rng && rng, T && t) const
{
return insert(static_cast<Rng &&>(rng), static_cast<T &&>(t));
}
template(typename Rng, typename Rng2)(
requires range<Rng> AND range<Rng2>)
insert_result_t<Rng, Rng2> operator()(Rng && rng, Rng2 && rng2) const
{
static_assert(!is_infinite<Rng>::value,
"Attempting to insert an infinite range into a container");
return insert(static_cast<Rng &&>(rng), static_cast<Rng2 &&>(rng2));
}
template(typename Rng, typename T)(
requires range<Rng>)
insert_result_t<Rng, std::initializer_list<T> &> //
operator()(Rng && rng, std::initializer_list<T> rng2) const
{
return insert(static_cast<Rng &&>(rng), rng2);
}
template(typename Rng, typename I, typename S)(
requires range<Rng> AND sentinel_for<S, I> AND (!range<S>)) //
insert_result_t<Rng, I, S> operator()(Rng && rng, I i, S j) const
{
return insert(static_cast<Rng &&>(rng), std::move(i), std::move(j));
}
template(typename Rng, typename I, typename T)(
requires range<Rng> AND input_iterator<I> AND
(!range<T>) AND constructible_from<range_value_t<Rng>, T>)
insert_result_t<Rng, I, T> operator()(Rng && rng, I p, T && t) const
{
return insert(
static_cast<Rng &&>(rng), std::move(p), static_cast<T &&>(t));
}
template(typename Rng, typename I, typename Rng2)(
requires range<Rng> AND input_iterator<I> AND range<Rng2>)
insert_result_t<Rng, I, Rng2> operator()(Rng && rng, I p, Rng2 && rng2) const
{
static_assert(!is_infinite<Rng>::value,
"Attempting to insert an infinite range into a container");
return insert(
static_cast<Rng &&>(rng), std::move(p), static_cast<Rng2 &&>(rng2));
}
template(typename Rng, typename I, typename T)(
requires range<Rng> AND input_iterator<I>)
insert_result_t<Rng, I, std::initializer_list<T> &> //
operator()(Rng && rng, I p, std::initializer_list<T> rng2) const
{
return insert(static_cast<Rng &&>(rng), std::move(p), rng2);
}
template(typename Rng, typename I, typename N, typename T)(
requires range<Rng> AND input_iterator<I> AND integral<N> AND
(!range<T>) AND constructible_from<range_value_t<Rng>, T>)
insert_result_t<Rng, I, N, T> operator()(Rng && rng, I p, N n, T && t) const
{
return insert(
static_cast<Rng &&>(rng), std::move(p), n, static_cast<T &&>(t));
}
template(typename Rng, typename P, typename I, typename S)(
requires range<Rng> AND input_iterator<P> AND sentinel_for<S, I> AND
(!range<S>)) //
insert_result_t<Rng, P, I, S> operator()(Rng && rng, P p, I i, S j) const
{
return insert(
static_cast<Rng &&>(rng), std::move(p), std::move(i), std::move(j));
}
};
} // namespace adl_insert_detail
/// \endcond
/// \ingroup group-actions
RANGES_INLINE_VARIABLE(adl_insert_detail::insert_fn, insert)
namespace actions
{
using ranges::insert;
}
} // namespace ranges
#include <range/v3/detail/epilogue.hpp>
#endif

View File

@@ -0,0 +1,68 @@
/// \file
// Range v3 library
//
// Copyright Eric Niebler 2013-present
//
// 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)
//
// Project home: https://github.com/ericniebler/range-v3
//
#ifndef RANGES_V3_ACTION_JOIN_HPP
#define RANGES_V3_ACTION_JOIN_HPP
#include <vector>
#include <meta/meta.hpp>
#include <range/v3/range_fwd.hpp>
#include <range/v3/action/action.hpp>
#include <range/v3/action/concepts.hpp>
#include <range/v3/action/push_back.hpp>
#include <range/v3/iterator/concepts.hpp>
#include <range/v3/iterator/traits.hpp>
#include <range/v3/utility/static_const.hpp>
#include <range/v3/detail/prologue.hpp>
namespace ranges
{
/// \addtogroup group-actions
/// @{
namespace actions
{
template<typename Rng>
using join_action_value_t_ =
meta::if_c<(bool)ranges::container<range_value_t<Rng>>, //
range_value_t<Rng>, //
std::vector<range_value_t<range_value_t<Rng>>>>;
struct join_fn
{
template(typename Rng)(
requires input_range<Rng> AND input_range<range_value_t<Rng>> AND
semiregular<join_action_value_t_<Rng>>)
join_action_value_t_<Rng> operator()(Rng && rng) const
{
join_action_value_t_<Rng> ret;
auto last = ranges::end(rng);
for(auto it = begin(rng); it != last; ++it)
push_back(ret, *it);
return ret;
}
};
/// \relates actions::join_fn
/// \sa action_closure
RANGES_INLINE_VARIABLE(action_closure<join_fn>, join)
} // namespace actions
/// @}
} // namespace ranges
#include <range/v3/detail/epilogue.hpp>
#endif

View File

@@ -0,0 +1,149 @@
/// \file
// Range v3 library
//
// Copyright Eric Niebler 2013-present
//
// 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)
//
// Project home: https://github.com/ericniebler/range-v3
//
#ifndef RANGES_V3_ACTION_PUSH_BACK_HPP
#define RANGES_V3_ACTION_PUSH_BACK_HPP
#include <utility>
#include <meta/meta.hpp>
#include <range/v3/range_fwd.hpp>
#include <range/v3/action/action.hpp>
#include <range/v3/action/insert.hpp>
#include <range/v3/detail/with_braced_init_args.hpp>
#include <range/v3/functional/bind_back.hpp>
#include <range/v3/utility/static_const.hpp>
#include <range/v3/detail/prologue.hpp>
namespace ranges
{
/// \addtogroup group-actions
/// @{
/// \cond
namespace adl_push_back_detail
{
/// \endcond
template<typename Cont, typename T>
using push_back_t = decltype(static_cast<void>(
unwrap_reference(std::declval<Cont &>()).push_back(std::declval<T>())));
template<typename Cont, typename Rng>
using insert_t = decltype(static_cast<void>(
ranges::insert(std::declval<Cont &>(), std::declval<sentinel_t<Cont>>(),
std::declval<Rng>())));
template(typename Cont, typename T)(
requires lvalue_container_like<Cont> AND
(!range<T>) AND constructible_from<range_value_t<Cont>, T>)
push_back_t<Cont, T> push_back(Cont && cont, T && t)
{
unwrap_reference(cont).push_back(static_cast<T &&>(t));
}
template(typename Cont, typename Rng)(
requires lvalue_container_like<Cont> AND range<Rng>)
insert_t<Cont, Rng> push_back(Cont && cont, Rng && rng)
{
ranges::insert(cont, end(cont), static_cast<Rng &&>(rng));
}
/// \cond
// clang-format off
/// \concept can_push_back_frag_
/// \brief The \c can_push_back_frag_ concept
template<typename Rng, typename T>
CPP_requires(can_push_back_frag_,
requires(Rng && rng, T && t) //
(
push_back(rng, (T &&) t)
));
/// \concept can_push_back_
/// \brief The \c can_push_back_ concept
template<typename Rng, typename T>
CPP_concept can_push_back_ =
CPP_requires_ref(adl_push_back_detail::can_push_back_frag_, Rng, T);
// clang-format on
/// \endcond
struct push_back_fn
{
template<typename T>
constexpr auto operator()(T && val) const
{
return make_action_closure(
bind_back(push_back_fn{}, static_cast<T &&>(val)));
}
template(typename T)(
requires range<T &>)
constexpr auto operator()(T & t) const
{
return make_action_closure(
bind_back(push_back_fn{}, detail::reference_wrapper_<T>(t)));
}
template<typename T>
constexpr auto operator()(std::initializer_list<T> val) const
{
return make_action_closure(bind_back(push_back_fn{}, val));
}
template(typename Rng, typename T)(
requires input_range<Rng> AND can_push_back_<Rng, T> AND
(range<T> || constructible_from<range_value_t<Rng>, T>)) //
Rng operator()(Rng && rng, T && t) const //
{
push_back(rng, static_cast<T &&>(t));
return static_cast<Rng &&>(rng);
}
template(typename Rng, typename T)(
requires input_range<Rng> AND
can_push_back_<Rng, std::initializer_list<T>> AND
constructible_from<range_value_t<Rng>, T const &>)
Rng operator()(Rng && rng, std::initializer_list<T> t) const //
{
push_back(rng, t);
return static_cast<Rng &&>(rng);
}
/// \cond
template<typename Rng, typename T>
invoke_result_t<push_back_fn, Rng, T &> //
operator()(Rng && rng, detail::reference_wrapper_<T> r) const
{
return (*this)(static_cast<Rng &&>(rng), r.get());
}
/// \endcond
};
/// \cond
} // namespace adl_push_back_detail
/// \endcond
namespace actions
{
RANGES_INLINE_VARIABLE(adl_push_back_detail::push_back_fn, push_back)
} // namespace actions
using actions::push_back;
/// @}
} // namespace ranges
#include <range/v3/detail/epilogue.hpp>
#endif

View File

@@ -0,0 +1,149 @@
/// \file
// Range v3 library
//
// Copyright Eric Niebler 2013-present
//
// 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)
//
// Project home: https://github.com/ericniebler/range-v3
//
#ifndef RANGES_V3_ACTION_PUSH_FRONT_HPP
#define RANGES_V3_ACTION_PUSH_FRONT_HPP
#include <utility>
#include <meta/meta.hpp>
#include <range/v3/range_fwd.hpp>
#include <range/v3/action/action.hpp>
#include <range/v3/action/insert.hpp>
#include <range/v3/detail/with_braced_init_args.hpp>
#include <range/v3/functional/bind_back.hpp>
#include <range/v3/utility/static_const.hpp>
#include <range/v3/detail/prologue.hpp>
namespace ranges
{
/// \addtogroup group-actions
/// @{
/// \cond
namespace adl_push_front_detail
{
/// \endcond
template<typename Cont, typename T>
using push_front_t = decltype(static_cast<void>(
unwrap_reference(std::declval<Cont &>()).push_front(std::declval<T>())));
template<typename Cont, typename Rng>
using insert_t = decltype(static_cast<void>(
ranges::insert(std::declval<Cont &>(), std::declval<iterator_t<Cont>>(),
std::declval<Rng>())));
template(typename Cont, typename T)(
requires lvalue_container_like<Cont> AND
(!range<T>) AND constructible_from<range_value_t<Cont>, T>)
push_front_t<Cont, T> push_front(Cont && cont, T && t)
{
unwrap_reference(cont).push_front(static_cast<T &&>(t));
}
template(typename Cont, typename Rng)(
requires lvalue_container_like<Cont> AND range<Rng>)
insert_t<Cont, Rng> push_front(Cont && cont, Rng && rng)
{
ranges::insert(cont, begin(cont), static_cast<Rng &&>(rng));
}
/// \cond
// clang-format off
/// \concept can_push_front_frag_
/// \brief The \c can_push_front_frag_ concept
template<typename Rng, typename T>
CPP_requires(can_push_front_frag_,
requires(Rng && rng, T && t) //
(
push_front(rng, (T &&) t)
));
/// \concept can_push_front_
/// \brief The \c can_push_front_ concept
template<typename Rng, typename T>
CPP_concept can_push_front_ =
CPP_requires_ref(adl_push_front_detail::can_push_front_frag_, Rng, T);
// clang-format on
/// \endcond
struct push_front_fn
{
template<typename T>
constexpr auto operator()(T && val) const
{
return make_action_closure(
bind_back(push_front_fn{}, static_cast<T &&>(val)));
}
template<typename T>
constexpr auto operator()(std::initializer_list<T> val) const
{
return make_action_closure(bind_back(push_front_fn{}, val));
}
template(typename T)(
requires range<T &>)
constexpr auto operator()(T & t) const
{
return make_action_closure(
bind_back(push_front_fn{}, detail::reference_wrapper_<T>(t)));
}
template(typename Rng, typename T)(
requires input_range<Rng> AND can_push_front_<Rng, T> AND
(range<T> || constructible_from<range_value_t<Rng>, T>)) //
Rng operator()(Rng && rng, T && t) const //
{
push_front(rng, static_cast<T &&>(t));
return static_cast<Rng &&>(rng);
}
template(typename Rng, typename T)(
requires input_range<Rng> AND
can_push_front_<Rng, std::initializer_list<T>> AND
constructible_from<range_value_t<Rng>, T const &>)
Rng operator()(Rng && rng, std::initializer_list<T> t) const //
{
push_front(rng, t);
return static_cast<Rng &&>(rng);
}
/// \cond
template<typename Rng, typename T>
invoke_result_t<push_front_fn, Rng, T &> //
operator()(Rng && rng, detail::reference_wrapper_<T> r) const
{
return (*this)(static_cast<Rng &&>(rng), r.get());
}
/// \endcond
};
/// \cond
} // namespace adl_push_front_detail
/// \endcond
namespace actions
{
RANGES_INLINE_VARIABLE(adl_push_front_detail::push_front_fn, push_front)
} // namespace actions
using actions::push_front;
/// @}
} // namespace ranges
#include <range/v3/detail/epilogue.hpp>
#endif

View File

@@ -0,0 +1,74 @@
/// \file
// Range v3 library
//
// Copyright Andrey Diduh 2019
//
// 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)
//
// Project home: https://github.com/ericniebler/range-v3
//
#ifndef RANGES_V3_ACTION_REMOVE_HPP
#define RANGES_V3_ACTION_REMOVE_HPP
#include <meta/meta.hpp>
#include <range/v3/range_fwd.hpp>
#include <range/v3/action/action.hpp>
#include <range/v3/action/erase.hpp>
#include <range/v3/algorithm/remove.hpp>
#include <range/v3/functional/bind_back.hpp>
#include <range/v3/range/concepts.hpp>
#include <range/v3/range/traits.hpp>
#include <range/v3/utility/static_const.hpp>
#include <range/v3/detail/prologue.hpp>
namespace ranges
{
/// \addtogroup group-actions
/// @{
namespace actions
{
struct remove_fn
{
template(typename V, typename P)(
requires (!range<V>))
constexpr auto operator()(V && value, P proj) const
{
return make_action_closure(
bind_back(remove_fn{}, static_cast<V &&>(value), std::move(proj)));
}
template<typename V>
constexpr auto operator()(V && value) const
{
return make_action_closure(
bind_back(remove_fn{}, static_cast<V &&>(value), identity{}));
}
template(typename Rng, typename V, typename P = identity)(
requires forward_range<Rng> AND permutable<iterator_t<Rng>> AND
erasable_range<Rng, iterator_t<Rng>, sentinel_t<Rng>> AND
indirect_relation<equal_to, projected<iterator_t<Rng>, P>,
V const *>)
Rng operator()(Rng && rng, V const & value, P proj = {}) const
{
auto it = ranges::remove(rng, value, std::move(proj));
ranges::erase(rng, it, ranges::end(rng));
return static_cast<Rng &&>(rng);
}
};
/// \relates actions::remove_fn
RANGES_INLINE_VARIABLE(remove_fn, remove)
} // namespace actions
/// @}
} // namespace ranges
#include <range/v3/detail/epilogue.hpp>
#endif

View File

@@ -0,0 +1,70 @@
/// \file
// Range v3 library
//
// Copyright Eric Niebler 2013-present
//
// 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)
//
// Project home: https://github.com/ericniebler/range-v3
//
#ifndef RANGES_V3_ACTION_REMOVE_IF_HPP
#define RANGES_V3_ACTION_REMOVE_IF_HPP
#include <utility>
#include <range/v3/range_fwd.hpp>
#include <range/v3/action/action.hpp>
#include <range/v3/action/erase.hpp>
#include <range/v3/algorithm/remove_if.hpp>
#include <range/v3/functional/bind_back.hpp>
#include <range/v3/functional/identity.hpp>
#include <range/v3/range/traits.hpp>
#include <range/v3/utility/static_const.hpp>
#include <range/v3/detail/prologue.hpp>
namespace ranges
{
// TODO Look at all the special cases handled by erase_if in Library Fundamentals 2
/// \addtogroup group-actions
/// @{
namespace actions
{
struct remove_if_fn
{
template(typename C, typename P = identity)(
requires (!range<C>))
constexpr auto operator()(C pred, P proj = P{}) const
{
return make_action_closure(
bind_back(remove_if_fn{}, std::move(pred), std::move(proj)));
}
template(typename Rng, typename C, typename P = identity)(
requires forward_range<Rng> AND
erasable_range<Rng &, iterator_t<Rng>, iterator_t<Rng>> AND
permutable<iterator_t<Rng>> AND
indirect_unary_predicate<C, projected<iterator_t<Rng>, P>>)
Rng operator()(Rng && rng, C pred, P proj = P{}) const
{
auto it = ranges::remove_if(rng, std::move(pred), std::move(proj));
ranges::erase(rng, it, ranges::end(rng));
return static_cast<Rng &&>(rng);
}
};
/// \relates actions::remove_if_fn
RANGES_INLINE_VARIABLE(remove_if_fn, remove_if)
} // namespace actions
/// @}
} // namespace ranges
#include <range/v3/detail/epilogue.hpp>
#endif

View File

@@ -0,0 +1,55 @@
/// \file
// Range v3 library
//
// Copyright Eric Niebler 2013-present
// Copyright Gonzalo Brito Gadeschi 2017
//
// 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)
//
// Project home: https://github.com/ericniebler/range-v3
//
#ifndef RANGES_V3_ACTION_REVERSE_HPP
#define RANGES_V3_ACTION_REVERSE_HPP
#include <range/v3/range_fwd.hpp>
#include <range/v3/action/action.hpp>
#include <range/v3/algorithm/reverse.hpp>
#include <range/v3/iterator/concepts.hpp>
#include <range/v3/range/traits.hpp>
#include <range/v3/utility/static_const.hpp>
#include <range/v3/detail/prologue.hpp>
namespace ranges
{
/// \addtogroup group-actions
/// @{
namespace actions
{
/// Reversed the source range in-place.
struct reverse_fn
{
template(typename Rng)(
requires bidirectional_range<Rng> AND permutable<iterator_t<Rng>>)
Rng operator()(Rng && rng) const
{
ranges::reverse(rng);
return static_cast<Rng &&>(rng);
}
};
/// \relates actions::reverse_fn
/// \sa action_closure
RANGES_INLINE_VARIABLE(action_closure<reverse_fn>, reverse)
} // namespace actions
/// @}
} // namespace ranges
#include <range/v3/detail/epilogue.hpp>
#endif

View File

@@ -0,0 +1,83 @@
/// \file
// Range v3 library
//
// Copyright Filip Matzner 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)
//
// Project home: https://github.com/ericniebler/range-v3
//
#ifndef RANGES_V3_ACTION_SHUFFLE_HPP
#define RANGES_V3_ACTION_SHUFFLE_HPP
#include <range/v3/range_fwd.hpp>
#include <range/v3/action/action.hpp>
#include <range/v3/algorithm/shuffle.hpp>
#include <range/v3/functional/bind.hpp>
#include <range/v3/functional/bind_back.hpp>
#include <range/v3/functional/invoke.hpp>
#include <range/v3/iterator/concepts.hpp>
#include <range/v3/iterator/traits.hpp>
#include <range/v3/utility/static_const.hpp>
#include <range/v3/detail/prologue.hpp>
namespace ranges
{
/// \addtogroup group-actions
/// @{
namespace actions
{
struct shuffle_fn
{
template(typename Gen)(
requires uniform_random_bit_generator<Gen>)
constexpr auto operator()(Gen & gen) const
{
return make_action_closure(
bind_back(shuffle_fn{}, detail::reference_wrapper_<Gen>(gen)));
}
template(typename Gen)(
requires uniform_random_bit_generator<Gen>)
constexpr auto operator()(Gen && gen) const
{
return make_action_closure(
bind_back(shuffle_fn{}, static_cast<Gen &&>(gen)));
}
template(typename Rng, typename Gen)(
requires random_access_range<Rng> AND permutable<iterator_t<Rng>> AND
uniform_random_bit_generator<std::remove_reference_t<Gen>> AND
convertible_to<invoke_result_t<Gen &>, range_difference_t<Rng>>)
Rng operator()(Rng && rng, Gen && gen) const
{
ranges::shuffle(rng, static_cast<Gen &&>(gen));
return static_cast<Rng &&>(rng);
}
/// \cond
template<typename Rng, typename T>
invoke_result_t<shuffle_fn, Rng, T &> //
operator()(Rng && rng, detail::reference_wrapper_<T> r) const
{
return (*this)(static_cast<Rng &&>(rng), r.get());
}
/// \endcond
};
/// \relates actions::shuffle_fn
/// \sa `action_closure`
RANGES_INLINE_VARIABLE(shuffle_fn, shuffle)
} // namespace actions
/// @}
} // namespace ranges
#include <range/v3/detail/epilogue.hpp>
#endif

View File

@@ -0,0 +1,154 @@
/// \file
// Range v3 library
//
// Copyright Eric Niebler 2013-present
//
// 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)
//
// Project home: https://github.com/ericniebler/range-v3
//
#ifndef RANGES_V3_ACTION_SLICE_HPP
#define RANGES_V3_ACTION_SLICE_HPP
#include <meta/meta.hpp>
#include <range/v3/range_fwd.hpp>
#include <range/v3/action/action.hpp>
#include <range/v3/action/erase.hpp>
#include <range/v3/functional/bind_back.hpp>
#include <range/v3/iterator/concepts.hpp>
#include <range/v3/iterator/operations.hpp>
#include <range/v3/iterator/traits.hpp>
#include <range/v3/utility/static_const.hpp>
#include <range/v3/view/interface.hpp>
#include <range/v3/detail/prologue.hpp>
namespace ranges
{
/// \addtogroup group-actions
/// @{
namespace actions
{
struct slice_fn
{
private:
template<typename D>
using diff_t = range_difference_t<D>;
public:
// Overloads for the pipe syntax: rng | actions::slice(from, to)
template(typename D)(
requires integral<D>)
constexpr auto operator()(D from, D to) const
{
return make_action_closure(bind_back(slice_fn{}, from, to));
}
template(typename D)(
requires integral<D>)
constexpr auto operator()(D from, detail::from_end_<D> to) const
{
return make_action_closure(bind_back(slice_fn{}, from, to));
}
template(typename D)(
requires integral<D>)
constexpr auto operator()(detail::from_end_<D> from, detail::from_end_<D> to)
const
{
return make_action_closure(bind_back(slice_fn{}, from, to));
}
template(typename D)(
requires integral<D>)
constexpr auto operator()(D from, end_fn const & to) const
{
return make_action_closure(bind_back(slice_fn{}, from, to));
}
template(typename D)(
requires integral<D>)
constexpr auto operator()(detail::from_end_<D> from, end_fn const & to) const
{
return make_action_closure(bind_back(slice_fn{}, from, to));
}
template(typename Rng, typename I = iterator_t<Rng>)(
requires forward_range<Rng> AND erasable_range<Rng &, I, I>)
Rng operator()(Rng && rng, diff_t<Rng> from, diff_t<Rng> to) const
{
RANGES_EXPECT(0 <= from && 0 <= to && from <= to);
RANGES_EXPECT(!sized_range<Rng> || to <= distance(rng));
ranges::actions::erase(rng, begin(rng), next(begin(rng), from));
ranges::actions::erase(rng, next(begin(rng), to - from), end(rng));
return static_cast<Rng &&>(rng);
}
template(typename Rng, typename I = iterator_t<Rng>)(
requires bidirectional_range<Rng> AND erasable_range<Rng &, I, I>)
Rng operator()(Rng && rng,
diff_t<Rng> from,
detail::from_end_<diff_t<Rng>> to) const
{
RANGES_EXPECT(0 <= from && to.dist_ <= 0);
RANGES_EXPECT(!sized_range<Rng> || from - to.dist_ <= distance(rng));
ranges::actions::erase(rng, begin(rng), next(begin(rng), from));
if(to.dist_ != 0)
{
auto const last = next(begin(rng), end(rng));
ranges::actions::erase(rng, prev(last, -to.dist_), last);
}
return static_cast<Rng &&>(rng);
}
template(typename Rng, typename I = iterator_t<Rng>)(
requires bidirectional_range<Rng> AND erasable_range<Rng &, I, I>)
Rng operator()(Rng && rng,
detail::from_end_<diff_t<Rng>> from,
detail::from_end_<diff_t<Rng>> to) const
{
RANGES_EXPECT(from.dist_ <= 0 && to.dist_ <= 0 && from.dist_ <= to.dist_);
RANGES_EXPECT(!sized_range<Rng> || 0 <= distance(rng) + from.dist_);
auto last = next(begin(rng), end(rng));
ranges::actions::erase(rng, prev(last, -to.dist_), last);
last = next(begin(rng), end(rng));
ranges::actions::erase(
rng, begin(rng), prev(last, to.dist_ - from.dist_));
return static_cast<Rng &&>(rng);
}
template(typename Rng, typename I = iterator_t<Rng>)(
requires forward_range<Rng> AND erasable_range<Rng &, I, I>)
Rng operator()(Rng && rng, diff_t<Rng> from, end_fn const &) const
{
RANGES_EXPECT(0 <= from);
RANGES_EXPECT(!sized_range<Rng> || from <= distance(rng));
ranges::actions::erase(rng, begin(rng), next(begin(rng), from));
return static_cast<Rng &&>(rng);
}
template(typename Rng, typename I = iterator_t<Rng>)(
requires bidirectional_range<Rng> AND erasable_range<Rng &, I, I>)
Rng operator()(Rng && rng,
detail::from_end_<diff_t<Rng>> from,
end_fn const &) const
{
RANGES_EXPECT(from.dist_ <= 0);
RANGES_EXPECT(!sized_range<Rng> || 0 <= distance(rng) + from.dist_);
auto const last = next(begin(rng), end(rng));
ranges::actions::erase(rng, begin(rng), prev(last, -from.dist_));
return static_cast<Rng &&>(rng);
}
};
/// \relates actions::slice_fn
RANGES_INLINE_VARIABLE(slice_fn, slice)
} // namespace actions
/// @}
} // namespace ranges
#include <range/v3/detail/epilogue.hpp>
#endif

View File

@@ -0,0 +1,64 @@
/// \file
// Range v3 library
//
// Copyright Eric Niebler 2013-present
//
// 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)
//
// Project home: https://github.com/ericniebler/range-v3
//
#ifndef RANGES_V3_ACTION_SORT_HPP
#define RANGES_V3_ACTION_SORT_HPP
#include <range/v3/range_fwd.hpp>
#include <range/v3/action/action.hpp>
#include <range/v3/algorithm/sort.hpp>
#include <range/v3/functional/bind_back.hpp>
#include <range/v3/functional/comparisons.hpp>
#include <range/v3/functional/identity.hpp>
#include <range/v3/iterator/concepts.hpp>
#include <range/v3/iterator/traits.hpp>
#include <range/v3/utility/static_const.hpp>
#include <range/v3/detail/prologue.hpp>
namespace ranges
{
/// \addtogroup group-actions
/// @{
namespace actions
{
struct sort_fn
{
template(typename C, typename P = identity)(
requires (!range<C>))
constexpr auto operator()(C pred, P proj = {}) const
{
return make_action_closure(
bind_back(sort_fn{}, std::move(pred), std::move(proj)));
}
template(typename Rng, typename C = less, typename P = identity)(
requires forward_range<Rng> AND sortable<iterator_t<Rng>, C, P>)
Rng operator()(Rng && rng, C pred = {}, P proj = {}) const
{
ranges::sort(rng, std::move(pred), std::move(proj));
return static_cast<Rng &&>(rng);
}
};
/// \relates actions::sort_fn
/// \sa action_closure
RANGES_INLINE_VARIABLE(action_closure<sort_fn>, sort)
} // namespace actions
/// @}
} // namespace ranges
#include <range/v3/detail/epilogue.hpp>
#endif

View File

@@ -0,0 +1,106 @@
/// \file
// Range v3 library
//
// Copyright Eric Niebler 2013-present
//
// 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)
//
// Project home: https://github.com/ericniebler/range-v3
//
#ifndef RANGES_V3_ACTION_SPLIT_HPP
#define RANGES_V3_ACTION_SPLIT_HPP
#include <vector>
#include <meta/meta.hpp>
#include <range/v3/range_fwd.hpp>
#include <range/v3/action/action.hpp>
#include <range/v3/action/concepts.hpp>
#include <range/v3/functional/bind_back.hpp>
#include <range/v3/iterator/concepts.hpp>
#include <range/v3/iterator/traits.hpp>
#include <range/v3/range/conversion.hpp>
#include <range/v3/utility/static_const.hpp>
#include <range/v3/view/split.hpp>
#include <range/v3/detail/prologue.hpp>
namespace ranges
{
/// \addtogroup group-actions
/// @{
namespace actions
{
struct split_fn
{
template<typename Rng>
using split_value_t =
meta::if_c<(bool)ranges::container<Rng>, //
uncvref_t<Rng>, std::vector<range_value_t<Rng>>>;
template(typename T)(
requires range<T &>)
constexpr auto operator()(T & t) const
{
return make_action_closure(
bind_back(split_fn{}, detail::reference_wrapper_<T>(t)));
}
template<typename T>
constexpr auto operator()(T && t) const
{
return make_action_closure(bind_back(split_fn{}, static_cast<T &&>(t)));
}
// BUGBUG something is not right with the actions. It should be possible
// to move a container into a split and have elements moved into the result.
template(typename Rng)(
requires input_range<Rng> AND indirectly_comparable<
iterator_t<Rng>, range_value_t<Rng> const *, ranges::equal_to>)
std::vector<split_value_t<Rng>> //
operator()(Rng && rng, range_value_t<Rng> val) const
{
return views::split(rng, std::move(val)) |
to<std::vector<split_value_t<Rng>>>();
}
template(typename Rng, typename Pattern)(
requires input_range<Rng> AND viewable_range<Pattern> AND
forward_range<Pattern> AND
indirectly_comparable<
iterator_t<Rng>,
iterator_t<Pattern>,
ranges::equal_to> AND
(forward_range<Rng> || detail::tiny_range<Pattern>)) //
std::vector<split_value_t<Rng>> operator()(Rng && rng, Pattern && pattern)
const
{
return views::split(rng, static_cast<Pattern &&>(pattern)) |
to<std::vector<split_value_t<Rng>>>();
}
/// \cond
template<typename Rng, typename T>
invoke_result_t<split_fn, Rng, T &> //
operator()(Rng && rng, detail::reference_wrapper_<T> r) const
{
return (*this)(static_cast<Rng &&>(rng), r.get());
}
/// \endcond
};
/// \relates actions::split_fn
RANGES_INLINE_VARIABLE(split_fn, split)
} // namespace actions
/// @}
} // namespace ranges
#include <range/v3/detail/epilogue.hpp>
#endif

View File

@@ -0,0 +1,90 @@
/// \file
// Range v3 library
//
// Copyright Eric Niebler 2013-present
//
// 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)
//
// Project home: https://github.com/ericniebler/range-v3
//
#ifndef RANGES_V3_ACTION_SPLIT_WHEN_HPP
#define RANGES_V3_ACTION_SPLIT_WHEN_HPP
#include <vector>
#include <meta/meta.hpp>
#include <range/v3/range_fwd.hpp>
#include <range/v3/action/action.hpp>
#include <range/v3/action/concepts.hpp>
#include <range/v3/functional/bind_back.hpp>
#include <range/v3/functional/invoke.hpp>
#include <range/v3/iterator/concepts.hpp>
#include <range/v3/iterator/traits.hpp>
#include <range/v3/range/conversion.hpp>
#include <range/v3/utility/static_const.hpp>
#include <range/v3/view/split_when.hpp>
#include <range/v3/detail/prologue.hpp>
namespace ranges
{
/// \addtogroup group-actions
/// @{
namespace actions
{
struct split_when_fn
{
template<typename Rng>
using split_value_t =
meta::if_c<(bool)ranges::container<Rng>, //
uncvref_t<Rng>, std::vector<range_value_t<Rng>>>;
template<typename Fun>
constexpr auto operator()(Fun fun) const
{
return make_action_closure(
bind_back(split_when_fn{}, static_cast<Fun &&>(fun)));
}
// BUGBUG something is not right with the actions. It should be possible
// to move a container into a split and have elements moved into the result.
template(typename Rng, typename Fun)(
requires forward_range<Rng> AND
invocable<Fun &, iterator_t<Rng>, sentinel_t<Rng>> AND
invocable<Fun &, iterator_t<Rng>, iterator_t<Rng>> AND
copy_constructible<Fun> AND
convertible_to<invoke_result_t<Fun &, iterator_t<Rng>,
sentinel_t<Rng>>,
std::pair<bool, iterator_t<Rng>>>)
std::vector<split_value_t<Rng>> operator()(Rng && rng, Fun fun) const
{
return views::split_when(rng, std::move(fun)) |
to<std::vector<split_value_t<Rng>>>();
}
template(typename Rng, typename Fun)(
requires forward_range<Rng> AND
predicate<Fun const &, range_reference_t<Rng>> AND
copy_constructible<Fun>)
std::vector<split_value_t<Rng>> operator()(Rng && rng, Fun fun) const
{
return views::split_when(rng, std::move(fun)) |
to<std::vector<split_value_t<Rng>>>();
}
};
/// \relates actions::split_when_fn
RANGES_INLINE_VARIABLE(split_when_fn, split_when)
} // namespace actions
/// @}
} // namespace ranges
#include <range/v3/detail/epilogue.hpp>
#endif

View File

@@ -0,0 +1,64 @@
/// \file
// Range v3 library
//
// Copyright Eric Niebler 2013-present
//
// 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)
//
// Project home: https://github.com/ericniebler/range-v3
//
#ifndef RANGES_V3_ACTION_STABLE_SORT_HPP
#define RANGES_V3_ACTION_STABLE_SORT_HPP
#include <range/v3/range_fwd.hpp>
#include <range/v3/action/action.hpp>
#include <range/v3/algorithm/stable_sort.hpp>
#include <range/v3/functional/bind_back.hpp>
#include <range/v3/functional/comparisons.hpp>
#include <range/v3/functional/identity.hpp>
#include <range/v3/iterator/concepts.hpp>
#include <range/v3/iterator/traits.hpp>
#include <range/v3/utility/static_const.hpp>
#include <range/v3/detail/prologue.hpp>
namespace ranges
{
/// \addtogroup group-actions
/// @{
namespace actions
{
struct stable_sort_fn
{
template(typename C, typename P = identity)(
requires (!range<C>))
constexpr auto operator()(C pred, P proj = P{}) const
{
return make_action_closure(
bind_back(stable_sort_fn{}, std::move(pred), std::move(proj)));
}
template(typename Rng, typename C = less, typename P = identity)(
requires forward_range<Rng> AND sortable<iterator_t<Rng>, C, P>)
Rng operator()(Rng && rng, C pred = C{}, P proj = P{}) const
{
ranges::stable_sort(rng, std::move(pred), std::move(proj));
return static_cast<Rng &&>(rng);
}
};
/// \relates actions::stable_sort_fn
/// \sa action_closure
RANGES_INLINE_VARIABLE(action_closure<stable_sort_fn>, stable_sort)
} // namespace actions
/// @}
} // namespace ranges
#include <range/v3/detail/epilogue.hpp>
#endif

View File

@@ -0,0 +1,79 @@
/// \file
// Range v3 library
//
// Copyright Eric Niebler 2013-present
//
// 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)
//
// Project home: https://github.com/ericniebler/range-v3
//
#ifndef RANGES_V3_ACTION_STRIDE_HPP
#define RANGES_V3_ACTION_STRIDE_HPP
#include <range/v3/range_fwd.hpp>
#include <range/v3/action/action.hpp>
#include <range/v3/action/erase.hpp>
#include <range/v3/functional/bind_back.hpp>
#include <range/v3/iterator/concepts.hpp>
#include <range/v3/iterator/operations.hpp>
#include <range/v3/iterator/traits.hpp>
#include <range/v3/utility/static_const.hpp>
#include <range/v3/detail/prologue.hpp>
namespace ranges
{
/// \addtogroup group-actions
/// @{
namespace actions
{
struct stride_fn
{
template(typename D)(
requires detail::integer_like_<D>)
constexpr auto operator()(D step) const
{
return make_action_closure(bind_back(stride_fn{}, step));
}
template(typename Rng, typename D = range_difference_t<Rng>)(
requires forward_range<Rng> AND
erasable_range<Rng &, iterator_t<Rng>, sentinel_t<Rng>> AND
permutable<iterator_t<Rng>>)
Rng operator()(Rng && rng, range_difference_t<Rng> const step) const
{
using I = iterator_t<Rng>;
using S = sentinel_t<Rng>;
RANGES_EXPECT(0 < step);
if(1 < step)
{
I first = ranges::begin(rng);
S const last = ranges::end(rng);
if(first != last)
{
for(I i = ranges::next(++first, step - 1, last); i != last;
advance(i, step, last), ++first)
{
*first = iter_move(i);
}
}
ranges::actions::erase(rng, first, last);
}
return static_cast<Rng &&>(rng);
}
};
/// \relates actions::stride_fn
RANGES_INLINE_VARIABLE(stride_fn, stride)
} // namespace actions
/// @}
} // namespace ranges
#include <range/v3/detail/epilogue.hpp>
#endif

View File

@@ -0,0 +1,64 @@
/// \file
// Range v3 library
//
// Copyright Eric Niebler 2013-present
//
// 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)
//
// Project home: https://github.com/ericniebler/range-v3
//
#ifndef RANGES_V3_ACTION_TAKE_HPP
#define RANGES_V3_ACTION_TAKE_HPP
#include <range/v3/range_fwd.hpp>
#include <range/v3/action/action.hpp>
#include <range/v3/action/erase.hpp>
#include <range/v3/functional/bind_back.hpp>
#include <range/v3/iterator/concepts.hpp>
#include <range/v3/iterator/operations.hpp>
#include <range/v3/iterator/traits.hpp>
#include <range/v3/utility/static_const.hpp>
#include <range/v3/detail/prologue.hpp>
namespace ranges
{
/// \addtogroup group-actions
/// @{
namespace actions
{
struct take_fn
{
template(typename Int)(
requires detail::integer_like_<Int>)
constexpr auto operator()(Int n) const
{
return make_action_closure(bind_back(take_fn{}, n));
}
template(typename Rng)(
requires forward_range<Rng> AND
erasable_range<Rng &, iterator_t<Rng>, sentinel_t<Rng>>)
Rng operator()(Rng && rng, range_difference_t<Rng> n) const
{
RANGES_EXPECT(n >= 0);
ranges::actions::erase(
rng, ranges::next(begin(rng), n, end(rng)), end(rng));
return static_cast<Rng &&>(rng);
}
};
/// \relates actions::take_fn
RANGES_INLINE_VARIABLE(take_fn, take)
} // namespace actions
/// @}
} // namespace ranges
#include <range/v3/detail/epilogue.hpp>
#endif

View File

@@ -0,0 +1,64 @@
/// \file
// Range v3 library
//
// Copyright Eric Niebler 2013-present
//
// 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)
//
// Project home: https://github.com/ericniebler/range-v3
//
#ifndef RANGES_V3_ACTION_TAKE_WHILE_HPP
#define RANGES_V3_ACTION_TAKE_WHILE_HPP
#include <range/v3/range_fwd.hpp>
#include <range/v3/action/action.hpp>
#include <range/v3/action/erase.hpp>
#include <range/v3/algorithm/find_if_not.hpp>
#include <range/v3/functional/bind_back.hpp>
#include <range/v3/iterator/concepts.hpp>
#include <range/v3/iterator/traits.hpp>
#include <range/v3/utility/static_const.hpp>
#include <range/v3/detail/prologue.hpp>
namespace ranges
{
/// \addtogroup group-actions
/// @{
namespace actions
{
struct take_while_fn
{
template(typename Fun)(
requires (!range<Fun>))
constexpr auto operator()(Fun fun) const
{
return make_action_closure(bind_back(take_while_fn{}, std::move(fun)));
}
template(typename Rng, typename Fun)(
requires forward_range<Rng> AND
erasable_range<Rng &, iterator_t<Rng>, sentinel_t<Rng>> AND
indirect_unary_predicate<Fun, iterator_t<Rng>>)
Rng operator()(Rng && rng, Fun fun) const
{
ranges::actions::erase(
rng, find_if_not(begin(rng), end(rng), std::move(fun)), end(rng));
return static_cast<Rng &&>(rng);
}
};
/// \relates actions::take_while_fn
RANGES_INLINE_VARIABLE(take_while_fn, take_while)
} // namespace actions
/// @}
} // namespace ranges
#include <range/v3/detail/epilogue.hpp>
#endif

View File

@@ -0,0 +1,65 @@
/// \file
// Range v3 library
//
// Copyright Eric Niebler 2013-present
//
// 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)
//
// Project home: https://github.com/ericniebler/range-v3
//
#ifndef RANGES_V3_ACTION_TRANSFORM_HPP
#define RANGES_V3_ACTION_TRANSFORM_HPP
#include <range/v3/range_fwd.hpp>
#include <range/v3/action/action.hpp>
#include <range/v3/algorithm/transform.hpp>
#include <range/v3/functional/bind_back.hpp>
#include <range/v3/functional/identity.hpp>
#include <range/v3/iterator/concepts.hpp>
#include <range/v3/iterator/traits.hpp>
#include <range/v3/utility/static_const.hpp>
#include <range/v3/detail/prologue.hpp>
namespace ranges
{
/// \addtogroup group-actions
/// @{
namespace actions
{
struct transform_fn
{
template(typename F, typename P = identity)(
requires (!range<F>))
constexpr auto operator()(F fun, P proj = P{}) const
{
return make_action_closure(
bind_back(transform_fn{}, std::move(fun), std::move(proj)));
}
template(typename Rng, typename F, typename P = identity)(
requires input_range<Rng> AND copy_constructible<F> AND
indirectly_writable<
iterator_t<Rng>,
indirect_result_t<F &, projected<iterator_t<Rng>, P>>>)
Rng operator()(Rng && rng, F fun, P proj = P{}) const
{
ranges::transform(rng, begin(rng), std::move(fun), std::move(proj));
return static_cast<Rng &&>(rng);
}
};
/// \relates actions::transform_fn
RANGES_INLINE_VARIABLE(transform_fn, transform)
} // namespace actions
/// @}
} // namespace ranges
#include <range/v3/detail/epilogue.hpp>
#endif

View File

@@ -0,0 +1,68 @@
/// \file
// Range v3 library
//
// Copyright Eric Niebler 2013-present
//
// 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)
//
// Project home: https://github.com/ericniebler/range-v3
//
#ifndef RANGES_V3_ACTION_UNIQUE_HPP
#define RANGES_V3_ACTION_UNIQUE_HPP
#include <range/v3/range_fwd.hpp>
#include <range/v3/action/action.hpp>
#include <range/v3/action/erase.hpp>
#include <range/v3/algorithm/unique.hpp>
#include <range/v3/functional/bind_back.hpp>
#include <range/v3/functional/comparisons.hpp>
#include <range/v3/functional/identity.hpp>
#include <range/v3/iterator/concepts.hpp>
#include <range/v3/range/traits.hpp>
#include <range/v3/utility/static_const.hpp>
#include <range/v3/detail/prologue.hpp>
namespace ranges
{
/// \addtogroup group-actions
/// @{
namespace actions
{
struct unique_fn
{
template(typename C, typename P = identity)(
requires (!range<C>))
constexpr auto operator()(C pred, P proj = P{}) const
{
return make_action_closure(
bind_back(unique_fn{}, std::move(pred), std::move(proj)));
}
template(typename Rng, typename C = equal_to, typename P = identity)(
requires forward_range<Rng> AND
erasable_range<Rng &, iterator_t<Rng>, sentinel_t<Rng>> AND
sortable<iterator_t<Rng>, C, P>)
Rng operator()(Rng && rng, C pred = C{}, P proj = P{}) const
{
auto it = ranges::unique(rng, std::move(pred), std::move(proj));
ranges::erase(rng, it, end(rng));
return static_cast<Rng &&>(rng);
}
};
/// \relates detail::unique_fn
/// \sa action_closure
RANGES_INLINE_VARIABLE(action_closure<unique_fn>, unique)
} // namespace actions
/// @}
} // namespace ranges
#include <range/v3/detail/epilogue.hpp>
#endif

View File

@@ -0,0 +1,73 @@
/// \file
// Range v3 library
//
// Copyright Andrey Diduh 2019
//
// 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)
//
// Project home: https://github.com/ericniebler/range-v3
//
#ifndef RANGES_V3_ACTION_UNSTABLE_REMOVE_IF_HPP
#define RANGES_V3_ACTION_UNSTABLE_REMOVE_IF_HPP
#include <utility>
#include <concepts/concepts.hpp>
#include <range/v3/range_fwd.hpp>
#include <range/v3/action/action.hpp>
#include <range/v3/action/erase.hpp>
#include <range/v3/algorithm/unstable_remove_if.hpp>
#include <range/v3/functional/bind_back.hpp>
#include <range/v3/functional/identity.hpp>
#include <range/v3/iterator/concepts.hpp>
#include <range/v3/range/access.hpp>
#include <range/v3/range/concepts.hpp>
#include <range/v3/detail/prologue.hpp>
namespace ranges
{
/// \addtogroup group-actions
/// @{
namespace actions
{
struct unstable_remove_if_fn
{
template(typename C, typename P = identity)(
requires (!range<C>))
constexpr auto operator()(C pred, P proj = P{}) const
{
return make_action_closure(
bind_back(unstable_remove_if_fn{}, std::move(pred), std::move(proj)));
}
template(typename Rng, typename C, typename P = identity)(
requires bidirectional_range<Rng> AND common_range<Rng> AND
permutable<iterator_t<Rng>> AND
indirect_unary_predicate<C, projected<iterator_t<Rng>, P>> AND
erasable_range<Rng, iterator_t<Rng>, iterator_t<Rng>>)
Rng operator()(Rng && rng, C pred, P proj = P{}) const
{
auto it = ranges::unstable_remove_if(ranges::begin(rng),
ranges::end(rng),
std::move(pred),
std::move(proj));
ranges::erase(rng, it, ranges::end(rng));
return static_cast<Rng &&>(rng);
}
};
/// \sa `actions::unstable_remove_if_fn`
RANGES_INLINE_VARIABLE(unstable_remove_if_fn, unstable_remove_if)
} // namespace actions
/// @}
} // namespace ranges
#include <range/v3/detail/epilogue.hpp>
#endif // RANGES_V3_ACTION_UNSTABLE_REMOVE_IF_HPP