Skip to content

Commit

Permalink
1
Browse files Browse the repository at this point in the history
  • Loading branch information
lackhole committed Aug 24, 2024
1 parent 5ddb140 commit f765218
Show file tree
Hide file tree
Showing 7 changed files with 749 additions and 383 deletions.
22 changes: 22 additions & 0 deletions include/preview/__functional/fold.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//
// Created by yonggyulee on 2024. 8. 23.
//

#ifndef PREVIEW_FUNCTIONAL_FOLD_H_
#define PREVIEW_FUNCTIONAL_FOLD_H_

namespace preview {

template<typename F, typename Arg, typename... Args, std::enable_if_t<(sizeof...(Args) > 0)>>
constexpr auto fold_left1(F&& f, Arg&& arg, Args&&... args) {
return f(std::forward<Arg>(arg))
}

template<typename F, typename Arg>
constexpr auto fold_left1(F&& f, Arg&& arg) {
return f(std::forward<Arg>(arg));
}

} // namespace preview

#endif // PREVIEW_INCLUDE_PREVIEW___FUNCTIONAL_FOLD_H_
115 changes: 47 additions & 68 deletions include/preview/__ranges/begin.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@
#include <cstddef>
#include <type_traits>

#include "preview/__core/decay_copy.h"
#include "preview/__core/inline_variable.h"
#include "preview/__iterator/input_or_output_iterator.h"
#include "preview/__type_traits/detail/return_category.h"
#include "preview/__ranges/enable_borrowed_range.h"
#include "preview/__core/decay_copy.h"
#include "preview/__type_traits/disjunction.h"
#include "preview/__type_traits/bool_constant.h"
#include "preview/__type_traits/detail/tag.h"
#include "preview/__type_traits/is_class_or_enum.h"
#include "preview/__type_traits/is_complete.h"
#include "preview/__type_traits/remove_cvref.h"
#include "preview/__type_traits/void_t.h"
Expand All @@ -22,79 +23,57 @@ namespace preview {
namespace ranges {
namespace detail {

using preview::detail::return_category;

template<typename T, bool = std::is_array<remove_cvref_t<T>>::value>
struct begin_array_check : std::false_type {
using category = return_category<0>;
};
template<typename T>
struct begin_array_check<T, true> : std::true_type {
using category = return_category<1, decltype(std::declval<T>() + 0)>;
template<typename T, template<typename, typename...> class = always_true, typename = void>
struct has_member_begin : std::false_type {};
template<typename T, template<typename, typename...> class Constraint>
struct has_member_begin<T, Constraint, void_t<decltype(preview_decay_copy(std::declval<T>().begin()))>>
: Constraint<decltype(preview_decay_copy(std::declval<T>().begin()))> {
};

template<typename T, typename = void>
struct begin_member_check : std::false_type {
using category = return_category<0>;
};
template<typename T>
struct begin_member_check<T, void_t<decltype(preview_decay_copy(std::declval<T>().begin()))>>
: input_or_output_iterator<decltype(preview_decay_copy(std::declval<T>().begin()))> {
using category = return_category<2, decltype(preview_decay_copy(std::declval<T>().begin()))>;
};
namespace begin_test_adl {

template<typename T, typename = void>
struct begin_global_check : std::false_type {
using category = return_category<0>;
};
template<typename T>
struct begin_global_check<T, void_t<decltype(preview_decay_copy(begin(std::declval<T>())))>>
: input_or_output_iterator<decltype(preview_decay_copy(begin(std::declval<T>())))> {
using category = return_category<3, decltype(preview_decay_copy(begin(std::declval<T>())))>;
template<typename T, template<typename, typename...> class = always_true, typename = void>
struct has_adl_begin : std::false_type {};
template<typename T, template<typename, typename...> class Constraint>
struct has_adl_begin<T, Constraint, void_t<decltype(preview_decay_copy(begin(std::declval<T>())))>>
: Constraint<decltype(preview_decay_copy(begin(std::declval<T>())))> {
};

template<typename T, bool = begin_member_check<T>::value /* false */>
struct begin_category_impl_2 : begin_global_check<T> {};
template<typename T>
struct begin_category_impl_2<T, true> : begin_member_check<T> {};

template<typename T, bool = begin_array_check<T>::value /* false */>
struct begin_category_impl : begin_category_impl_2<T> {};
template<typename T>
struct begin_category_impl<T, true> : begin_array_check<T> {};

template<typename T>
struct begin_category
: std::conditional_t<
disjunction<
std::is_lvalue_reference<T>,
enable_borrowed_range_t<remove_cvref_t<T>>
>::value,
typename begin_category_impl<T>::category,
return_category<0>
> {};

template<typename T, typename R>
constexpr R ranges_begin(T&& t, return_category<1, R>) {
static_assert(is_complete<std::remove_all_extents_t<std::remove_reference_t<T>>>::value, "Array element must be complete type");
return t + 0;
}

template<typename T, typename R>
constexpr R ranges_begin(T&& t, return_category<2, R>) {
return preview_decay_copy(t.begin());
}

template<typename T, typename R>
constexpr R ranges_begin(T&& t, return_category<3, R>) {
return preview_decay_copy(begin(t));
}
} // namespace begin_test_adl

struct begin_niebloid {
private:
template<typename T>
constexpr typename begin_category<T&&>::return_type
operator()(T&& t) const {
return ranges_begin(std::forward<T>(t), detail::begin_category<T&&>{});
using tag = preview::detail::conditional_tag<
std::is_array<remove_cvref_t<T>>,
has_member_begin<T, input_or_output_iterator>,
conjunction<
is_class_or_enum<remove_cvref_t<T>>,
begin_test_adl::has_adl_begin<T, input_or_output_iterator>
>
>;

template<typename T>
constexpr auto call(T&& t, preview::detail::tag_1) const {
static_assert(is_complete<std::remove_all_extents_t<std::remove_reference_t<T>>>::value, "Array element must be complete type");
return t + 0;
}

template<typename T>
constexpr auto call(T&& t, preview::detail::tag_2) const {
return preview_decay_copy(t.begin());
}

public:
template<typename T, std::enable_if_t<conjunction<
negation<conjunction<
std::is_rvalue_reference<T&&>,
bool_constant<( enable_borrowed_range<std::remove_cv_t<T>> == false )>
>>,
bool_constant<(tag<T>::value > 0)>
>::value, int> = 0>
constexpr auto operator()(T&& t) const {
return call(std::forward<T>(t), tag<T>{});
}
};

Expand Down
4 changes: 1 addition & 3 deletions include/preview/__ranges/distance.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,7 @@ struct distance_niebloid {
return result;
}

template<typename I, typename S, std::enable_if_t<
sized_sentinel_for<S, std::decay_t<I>>
::value, int> = 0>
template<typename I, typename S, std::enable_if_t<sized_sentinel_for<S, std::decay_t<I>>::value, int> = 0>
constexpr iter_difference_t<std::decay_t<I>> operator()(I&& first, S last) const {
return last - static_cast<const std::decay_t<I>&>(first);
}
Expand Down
Loading

0 comments on commit f765218

Please sign in to comment.