Skip to content

Commit

Permalink
upd
Browse files Browse the repository at this point in the history
  • Loading branch information
wjr-z committed Jan 23, 2024
1 parent a12f1bb commit a2f2f8f
Show file tree
Hide file tree
Showing 7 changed files with 192 additions and 130 deletions.
75 changes: 0 additions & 75 deletions include/wjr/action/unroll.hpp

This file was deleted.

5 changes: 2 additions & 3 deletions include/wjr/compressed_pair.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -373,9 +373,8 @@ namespace std {
template <typename T, typename U,
std::enable_if_t<std::conjunction_v<wjr::is_swappable<T>, wjr::is_swappable<U>>,
int> = 0>
constexpr void
swap(wjr::compressed_pair<T, U> &lhs,
wjr::compressed_pair<T, U> &rhs) noexcept(noexcept(lhs.swap(rhs))) {
constexpr void swap(wjr::compressed_pair<T, U> &lhs,
wjr::compressed_pair<T, U> &rhs) noexcept(noexcept(lhs.swap(rhs))) {
lhs.swap(rhs);
}

Expand Down
19 changes: 0 additions & 19 deletions include/wjr/constant_flag/constant_flag.hpp

This file was deleted.

Empty file.
25 changes: 25 additions & 0 deletions include/wjr/math/bit.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#ifndef WJR_MATH_BIT_HPP__
#define WJR_MATH_BIT_HPP__

#include <wjr/type_traits.hpp>

namespace wjr {

template <typename T, std::enable_if_t<is_unsigned_integral_v<T>, int> = 0>
WJR_CONST WJR_INTRINSIC_CONSTEXPR bool is_power_of_two(T n) {
return (n & (n - 1)) == 0;
}

template <typename T, std::enable_if_t<is_unsigned_integral_v<T>, int> = 0>
WJR_CONST WJR_INTRINSIC_CONSTEXPR bool has_single_bit(T n) {
return n != 0 && is_power_of_two(n);
}

template <typename T, std::enable_if_t<is_unsigned_integral_v<T>, int> = 0>
WJR_CONST WJR_INTRINSIC_CONSTEXPR T lowbit(T n) {
return n & -n;
}

} // namespace wjr

#endif // WJR_MATH_BIT_HPP__
81 changes: 81 additions & 0 deletions include/wjr/span.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#ifndef WJR_SPAN_HPP__
#define WJR_SPAN_HPP__

#include <wjr/compressed_pair.hpp>

namespace wjr {

inline constexpr std::size_t dynamic_extent = std::numeric_limits<std::size_t>::max();

template <typename T, size_t Extend>
struct __span_static_storage {

__span_static_storage() = default;
__span_static_storage(const __span_static_storage &) = default;
__span_static_storage &operator=(const __span_static_storage &) = default;

__span_static_storage(T *p, size_t s) : ptr(p) { WJR_ASSERT(s == size); }

T *ptr;
static constexpr size_t size = Extend;
};

template <typename T>
struct __span_dynamic_storage {

__span_dynamic_storage() = default;
__span_dynamic_storage(const __span_dynamic_storage &) = default;
__span_dynamic_storage &operator=(const __span_dynamic_storage &) = default;

__span_dynamic_storage(T *p, size_t s) : ptr(p), size(s) {}

T *ptr;
size_t size = 0;
};

template <typename Iter, typename T>
struct __is_span_iterator
: std::conjunction<is_contiguous_iterator<Iter>,
std::is_convertible<iter_reference_t<Iter>, T>> {};

template <typename T, size_t Extend = dynamic_extent>
class span {
static constexpr bool __is_dynamic = Extend == dynamic_extent;
using __storage = std::conditional_t<__is_dynamic, __span_dynamic_storage<T>,
__span_static_storage<T, Extend>>;

public:
using element_type = T;
using value_type = std::remove_cv_t<T>;
using size_type = size_t;
using difference_type = ptrdiff_t;
using pointer = T *;
using const_pointer = const T *;
using reference = T &;
using const_reference = const T &;
using iterator = pointer;
using const_iterator = const_pointer;
using reverse_iterator = std::reverse_iterator<iterator>;
using const_reverse_iterator = std::reverse_iterator<const_iterator>;

template <size_t Ex = Extend,
std::enable_if_t<Ex == dynamic_extent || Ex == 0, int> = 0>
constexpr span() noexcept : storage() {}

template <typename It = T,
std::enable_if_t<__is_span_iterator<It, T>::value && __is_dynamic, int> = 0>
constexpr span(It First, size_type Count) : storage(to_address(First), Count) {}

template <
typename It,
std::enable_if_t<__is_span_iterator<It, T>::value && !__is_dynamic, int> = 0>
constexpr explicit span(It First, size_type Count)
: storage(to_address(First), Count) {}

private:
__storage storage;
};

} // namespace wjr

#endif // WJR_SPAN_HPP__
117 changes: 84 additions & 33 deletions include/wjr/type_traits.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,34 +46,12 @@ template <typename T, typename... Args>
inline constexpr bool is_any_of_v = is_any_of<T, Args...>::value;

template <typename T>
using remove_ref_t = std::remove_reference_t<T>;

template <typename T>
using remove_cref_t = std::remove_const_t<remove_ref_t<T>>;
struct remove_cvref {
using type = std::remove_cv_t<std::remove_reference_t<T>>;
};

template <typename T>
using remove_cvref_t = std::remove_cv_t<remove_ref_t<T>>;

template <typename iter, typename = void>
struct is_contiguous_iterator_impl : std::is_pointer<iter> {};

template <typename iter>
struct is_contiguous_iterator_impl<iter, typename iter::is_contiguous_iterator>
: std::true_type {};

#if defined(WJR_CPP_20)
template <typename iter>
struct is_contiguous_iterator
: std::bool_constant<std::contiguous_iterator<iter> ||
is_contiguous_iterator_impl<iter>::value> {};
#else
template <typename iter>
struct is_contiguous_iterator : is_contiguous_iterator_impl<iter> {};
#endif

template <typename iter>
struct is_contiguous_iterator<std::reverse_iterator<iter>>
: is_contiguous_iterator<iter> {};
using remove_cvref_t = typename remove_cvref<T>::type;

template <size_t n>
struct __uint_selector {};
Expand Down Expand Up @@ -202,7 +180,7 @@ struct __is_swappable_with : std::false_type {};

template <typename T, typename U>
struct __is_swappable_with<
T, U, std::void_t<decltype(std::swap(std::declval<T>(), std::declval<U>()))>>
T, U, std::void_t<decltype(std::swap(std::declval<T &>(), std::declval<U &>()))>>
: std::true_type {};

template <typename T, typename U>
Expand All @@ -222,8 +200,9 @@ inline constexpr bool is_swappable_v = is_swappable<T>::value;

template <typename T, typename U>
struct __is_nothrow_swappable_with
: std::bool_constant<noexcept(std::swap(std::declval<T>(), std::declval<U>())) &&
noexcept(std::swap(std::declval<U>(), std::declval<T>()))> {};
: std::bool_constant<noexcept(std::swap(std::declval<T &>(), std::declval<U &>())) &&
noexcept(std::swap(std::declval<U &>(), std::declval<T &>()))> {
};

template <typename T, typename U>
struct is_nothrow_swappable_with
Expand Down Expand Up @@ -292,14 +271,86 @@ WJR_INTRINSIC_CONSTEXPR size_t abs_cast(size_t n) {
return n;
}

#if defined(WJR_CPP_20)
// C++ 17 concept adapt

template <typename Derived, typename Base>
struct is_derived_from
: std::conjunction<
std::is_base_of<Base, Derived>,
std::is_convertible<const volatile Derived *, const volatile Base *>> {};

template <typename Derived, typename Base>
inline constexpr bool is_derived_from_v = is_derived_from<Derived, Base>::Value;

template <typename From, typename To, typename = void>
struct __is_convertible_to_helper : std::false_type {};

template <typename From, typename To>
struct __is_convertible_to_helper<
From, To, std::void_t<decltype(static_cast<To>(std::declval<From>()))>>
: std::true_type {};

template <typename From, typename To>
struct is_convertible_to : std::conjunction<std::is_convertible<From, To>,
__is_convertible_to_helper<From, To, void>> {
};

template <typename From, typename To>
inline constexpr bool is_convertible_to_v = is_convertible_to<From, To>::value;

template <typename Ptr, typename = void>
struct __has_to_address_impl : std::false_type {};

template <typename Ptr>
struct __has_to_address_impl<
Ptr, std::void_t<decltype(typename std::pointer_traits<Ptr>::to_address(
std::declval<const Ptr &>()))>> : std::true_type {};

template <typename Ptr>
struct __has_to_address : __has_to_address_impl<remove_cvref_t<Ptr>, void> {};

template <typename T>
using make_template_constant_t = T;
#else
constexpr T *to_address(T *p) noexcept {
static_assert(!std::is_function_v<T>);
return p;
}

template <typename Ptr>
constexpr auto to_address(const Ptr &p) noexcept {
if constexpr (__has_to_address<Ptr>::value) {
return std::pointer_traits<Ptr>::to_address(p);
} else {
return to_address(p.operator->());
}
}

template <typename T>
using make_template_constant_t = std::add_lvalue_reference_t<std::add_const_t<T>>;
using iter_reference_t = decltype(*std::declval<T &>());

template <typename iter, typename = void>
struct is_contiguous_iterator_impl : std::is_pointer<iter> {};

template <typename iter>
struct is_contiguous_iterator_impl<iter, typename iter::is_contiguous_iterator>
: std::true_type {};

#if defined(WJR_CPP_20)
template <typename iter>
struct is_contiguous_iterator
: std::bool_constant<std::contiguous_iterator<iter> ||
is_contiguous_iterator_impl<iter>::value> {};
#else
template <typename iter>
struct is_contiguous_iterator : is_contiguous_iterator_impl<iter> {};
#endif

template <typename iter>
struct is_contiguous_iterator<std::reverse_iterator<iter>>
: is_contiguous_iterator<iter> {};

template <typename iter>
inline constexpr bool is_contiguous_iterator_v = is_contiguous_iterator<iter>::value;

} // namespace wjr

#endif // ! WJR_TYPE_TRAITS_HPP__

0 comments on commit a2f2f8f

Please sign in to comment.