Skip to content

Commit

Permalink
Added mismatch and split
Browse files Browse the repository at this point in the history
  • Loading branch information
whaeck committed Mar 25, 2024
1 parent 561dcf9 commit cf75f12
Show file tree
Hide file tree
Showing 5 changed files with 764 additions and 2 deletions.
2 changes: 1 addition & 1 deletion src/tools/std20/algorithm.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
//#include <nanorange/algorithm/min_element.hpp>
//#include <nanorange/algorithm/minmax.hpp>
//#include <nanorange/algorithm/minmax_element.hpp>
//#include <nanorange/algorithm/mismatch.hpp>
#include "tools/std20/algorithm/mismatch.hpp"
//#include <nanorange/algorithm/move.hpp>
//#include <nanorange/algorithm/next_permutation.hpp>
//#include <nanorange/algorithm/none_of.hpp>
Expand Down
132 changes: 132 additions & 0 deletions src/tools/std20/algorithm/mismatch.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
// nanorange/algorithm/mismatch.hpp
//
// Copyright (c) 2018 Tristan Brindle (tcbrindle at gmail dot com)
// 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)

#ifndef NANORANGE_ALGORITHM_MISMATCH_HPP_INCLUDED
#define NANORANGE_ALGORITHM_MISMATCH_HPP_INCLUDED

#include "tools/std20/detail/algorithm/result_types.hpp"
#include "tools/std20/ranges.hpp"

NANO_BEGIN_NAMESPACE

// [range.mismatch]

template <typename I1, typename I2>
using mismatch_result = in_in_result<I1, I2>;

namespace detail {

struct mismatch_fn {
private:
friend struct is_permutation_fn;

template <typename I1, typename S1, typename I2, typename Proj1,
typename Proj2, typename Pred>
static constexpr mismatch_result<I1, I2>
impl3(I1 first1, S1 last1, I2 first2, Pred& pred, Proj1& proj1, Proj2& proj2)
{
while (first1 != last1 &&
nano::invoke(pred, nano::invoke(proj1, *first1),
nano::invoke(proj2, *first2))) {
++first1;
++first2;
}

return {first1, first2};
}

template <typename I1, typename S1, typename I2, typename S2,
typename Proj1, typename Proj2, typename Pred>
static constexpr mismatch_result<I1, I2>
impl4(I1 first1, S1 last1, I2 first2, S2 last2, Pred& pred, Proj1& proj1,
Proj2& proj2)
{
while (first1 != last1 && first2 != last2 &&
nano::invoke(pred, nano::invoke(proj1, *first1),
nano::invoke(proj2, *first2))) {
++first1;
++first2;
}

return {first1, first2};
}

public:
// three legged
template <typename I1, typename S1, typename I2, typename Proj1 = identity,
typename Proj2 = identity, typename Pred = ranges::equal_to>
NANO_DEPRECATED constexpr std::enable_if_t<
input_iterator<I1> && sentinel_for<S1, I1> &&
input_iterator<std::decay_t<I2>> &&
!input_range<I1> &&
indirect_relation<Pred, projected<I1, Proj1>, projected<std::decay_t<I2>, Proj2>>,
mismatch_result<I1, std::decay_t<I2>>>
operator()(I1 first1, S1 last1, I2&& first2, Pred pred = Pred{},
Proj1 proj1 = Proj1{}, Proj2 proj2 = Proj2{}) const
{
return mismatch_fn::impl3(std::move(first1), std::move(last1),
std::forward<I2>(first2), pred,
proj1, proj2);
}

// range and a half
template <typename Rng1, typename I2, typename Proj1 = identity,
typename Proj2 = identity, typename Pred = ranges::equal_to>
NANO_DEPRECATED constexpr std::enable_if_t<
input_range<Rng1> && input_iterator<std::decay_t<I2>> &&
!input_range<I2> &&
indirect_relation<Pred, projected<iterator_t<Rng1>, Proj1>,
projected<std::decay_t<I2>, Proj2>>,
mismatch_result<borrowed_iterator_t<Rng1>, std::decay_t<I2>>>
operator()(Rng1&& rng1, I2&& first2, Pred pred = Pred{},
Proj1 proj1 = Proj1{}, Proj2 proj2 = Proj2{}) const
{
return mismatch_fn::impl3(nano::begin(rng1), nano::end(rng1),
std::forward<I2>(first2), pred,
proj1, proj2);
}

// four legged
template <typename I1, typename S1, typename I2, typename S2,
typename Proj1 = identity, typename Proj2 = identity,
typename Pred = ranges::equal_to>
constexpr std::enable_if_t<
input_iterator<I1> && sentinel_for<S1, I1> && input_iterator<I2> &&
sentinel_for<S2, I2> &&
indirect_relation<Pred, projected<I1, Proj1>, projected<I2, Proj2>>,
mismatch_result<I1, I2>>
operator()(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = Pred{},
Proj1 proj1 = Proj1{}, Proj2 proj2 = Proj2{}) const
{
return mismatch_fn::impl4(std::move(first1), std::move(last1),
std::move(first2), std::move(last2),
pred, proj1, proj2);
}

// two ranges
template <typename Rng1, typename Rng2, typename Proj1 = identity,
typename Proj2 = identity, typename Pred = ranges::equal_to>
constexpr std::enable_if_t<
input_range<Rng1> && input_range<Rng2> &&
indirect_relation<Pred, projected<iterator_t<Rng1>, Proj1>,
projected<iterator_t<Rng2>, Proj2>>,
mismatch_result<borrowed_iterator_t<Rng1>, borrowed_iterator_t<Rng2>>>
operator()(Rng1&& rng1, Rng2&& rng2, Pred pred = Pred{},
Proj1 proj1 = Proj1{}, Proj2 proj2 = Proj2{}) const
{
return mismatch_fn::impl4(nano::begin(rng1), nano::end(rng1),
nano::begin(rng2), nano::end(rng2),
pred, proj1, proj2);
}
};

} // namespace detail

NANO_INLINE_VAR(detail::mismatch_fn, mismatch)

NANO_END_NAMESPACE

#endif
172 changes: 172 additions & 0 deletions src/tools/std20/detail/algorithm/result_types.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
// nanorange/detail/algorithm/result_types.hpp
//
// Copyright (c) 2020 Boris Staletic (boris dot staletic at gmail dot com)
// Copyright (c) 2020 Tristan Brindle (tcbrindle at gmail dot com)
// 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)

#ifndef NANORANGE_DETAIL_ALGORITHM_RETURN_TYPES
#define NANORANGE_DETAIL_ALGORITHM_RETURN_TYPES

#include "tools/std20/detail/macros.hpp"
#include "tools/std20/detail/concepts/core.hpp"

#include <type_traits>

NANO_BEGIN_NAMESPACE

template <typename I, typename F>
struct in_fun_result {
NANO_NO_UNIQUE_ADDRESS I in;
NANO_NO_UNIQUE_ADDRESS F fun;

template <typename I2, typename F2,
std::enable_if_t<convertible_to<const I&, I2> &&
convertible_to<const F&, F2>, int> = 0>
constexpr operator in_fun_result<I2, F2>() const &
{
return {in, fun};
}

template <typename I2, typename F2,
std::enable_if_t<convertible_to<I, I2> &&
convertible_to<F, F2>, int> = 0>
constexpr operator in_fun_result<I2, F2>() &&
{
return {std::move(in), std::move(fun)};
}
};

template <typename I1, typename I2>
struct in_in_result {
NANO_NO_UNIQUE_ADDRESS I1 in1;
NANO_NO_UNIQUE_ADDRESS I2 in2;

template <typename II1, typename II2,
std::enable_if_t<convertible_to<const I1&, II1> &&
convertible_to<const I2&, II2>, int> = 0>
constexpr operator in_in_result<II1, II2>() const &
{
return {in1, in2};
}

template <typename II1, typename II2,
std::enable_if_t<convertible_to<I1, II1> &&
convertible_to<I2, II2>, int> = 0>
constexpr operator in_in_result<II1, II2>() &&
{
return {std::move(in1), std::move(in2)};
}
};

template <typename I, typename O>
struct in_out_result {
NANO_NO_UNIQUE_ADDRESS I in;
NANO_NO_UNIQUE_ADDRESS O out;

template <typename I2, typename O2,
std::enable_if_t<convertible_to<const I&, I2> &&
convertible_to<const O&, O2>, int> = 0>
constexpr operator in_out_result<I2, O2>() const &
{
return {in, out};
}

template <typename I2, typename O2,
std::enable_if_t<convertible_to<I, I2> &&
convertible_to<O, O2>, int> = 0>
constexpr operator in_out_result<I2, O2>() &&
{
return {std::move(in), std::move(out)};
}
};

template <typename I1, typename I2, typename O>
struct in_in_out_result {
NANO_NO_UNIQUE_ADDRESS I1 in1;
NANO_NO_UNIQUE_ADDRESS I2 in2;
NANO_NO_UNIQUE_ADDRESS O out;

template <typename II1, typename II2, typename O2,
std::enable_if_t<convertible_to<const I1&, II1> &&
convertible_to<const I2&, II2> &&
convertible_to<const O&, O2>, int> = 0>
constexpr operator in_in_out_result<II1, II2, O2>() const &
{
return {in1, in2, out};
}

template <typename II1, typename II2, typename O2,
std::enable_if_t<convertible_to<I1, II1> &&
convertible_to<I2, II2> &&
convertible_to<O, O2>, int> = 0>
constexpr operator in_in_out_result<II1, II2, O2>() &&
{
return {std::move(in1), std::move(in2), std::move(out)};
}
};

template <typename I, typename O1, typename O2>
struct in_out_out_result {
NANO_NO_UNIQUE_ADDRESS I in;
NANO_NO_UNIQUE_ADDRESS O1 out1;
NANO_NO_UNIQUE_ADDRESS O2 out2;

template <typename II, typename OO1, typename OO2,
std::enable_if_t<convertible_to<const I&, II> &&
convertible_to<const O1&, OO1> &&
convertible_to<const O2&, OO2>, int> = 0>
constexpr operator in_out_out_result<II, OO1, OO2>() const &
{
return {in, out1, out2};
}

template <typename II, typename OO1, typename OO2,
std::enable_if_t<convertible_to<I, II> &&
convertible_to<O1, OO1> &&
convertible_to<O2, OO2>, int> = 0>
constexpr operator in_out_out_result<II, OO1, OO2>() &&
{
return {std::move(in), std::move(out1), std::move(out2)};
}
};

template <typename T>
struct min_max_result {
NANO_NO_UNIQUE_ADDRESS T min;
NANO_NO_UNIQUE_ADDRESS T max;

template <typename T2,
std::enable_if_t<convertible_to<const T&, T2>, int> = 0>
constexpr operator min_max_result<T2>() const &
{
return {min, max};
}

template <typename T2,
std::enable_if_t<convertible_to<T, T2>, int> = 0>
constexpr operator min_max_result<T2>() &&
{
return {std::move(min), std::move(max)};
}
};

template <typename I>
struct in_found_result {
NANO_NO_UNIQUE_ADDRESS I in;
bool found;
template<class I2,
std::enable_if_t< convertible_to<const I&, I2>, int> = 0>
constexpr operator in_found_result<I2>() const & {
return {in, found};
}
template<class I2,
std::enable_if_t< convertible_to<const I&, I2>, int> = 0>
constexpr operator in_found_result<I2>() && {
return {std::move(in), found};
}
};

NANO_END_NAMESPACE

#endif
2 changes: 1 addition & 1 deletion src/tools/std20/views.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
#include "tools/std20/views/ref.hpp"
#include "tools/std20/views/reverse.hpp"
#include "tools/std20/views/single.hpp"
//#include "tools/std20/views/split.hpp"
#include "tools/std20/views/split.hpp"
#include "tools/std20/views/subrange.hpp"
#include "tools/std20/views/take.hpp"
#include "tools/std20/views/take_while.hpp"
Expand Down
Loading

0 comments on commit cf75f12

Please sign in to comment.