Created
May 18, 2020 03:12
-
-
Save ThePhD/27ef91a6820e7d5c8bc8022cebfb0d29 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <memory> | |
#include <limits> | |
#include <exception> | |
#include <optional> | |
#include <cstddef> | |
namespace std0 { | |
namespace detail { | |
template <typename Alloc> | |
using alloc_pointer = typename Alloc::pointer; | |
template <typename Alloc> | |
using alloc_const_pointer = typename Alloc::const_pointer; | |
template <typename Alloc> | |
using alloc_void_pointer = typename Alloc::const_pointer; | |
template <typename Alloc> | |
using alloc_const_void_pointer = typename Alloc::const_void_pointer; | |
template <typename Alloc> | |
using alloc_difference_type = typename Alloc::difference_type; | |
template <typename Alloc> | |
using alloc_size_type = typename Alloc::size_type; | |
template <typename Alloc> | |
using alloc_is_always_equal = typename Alloc::is_always_equal; | |
template <typename Alloc> | |
using alloc_alignment = std::integral_constant<std::align_val_t, Alloc::alignment>; | |
template <typename Alloc> | |
using alloc_propagate_on_container_copy_assignment = typename Alloc::propagate_on_container_copy_assignment; | |
template <typename Alloc> | |
using alloc_propagate_on_container_move_assignment = typename Alloc::propagate_on_container_move_assignment; | |
template <typename Alloc> | |
using alloc_propagate_on_container_swap = typename Alloc::propagate_on_container_swap; | |
template <typename Alloc, typename Other> | |
using alloc_rebind_alloc = typename Alloc::template rebind<Other>::other; | |
template <typename T, typename Alloc> | |
struct manually_rebound_allocator { | |
using type = Alloc; | |
}; | |
template <typename T, typename OtherT, typename... Args, template <typename...> typename Alloc> | |
struct manually_rebound_allocator<T, Alloc<OtherT, Args...>> { | |
using type = Alloc<T, Args...>; | |
}; | |
template <typename T, typename U> | |
concept convertible = std::is_convertible_v<T, U>; | |
template <typename Alloc, typename... Args> | |
using detect_is_allocate_noexcept = std::integral_constant<bool, noexcept(std::declval<Alloc&>().allocate(std::declval<Args>()...))>; | |
template <typename Alloc, typename... Args> | |
using detect_is_allocate_at_least_noexcept = std::integral_constant<bool, noexcept(std::declval<Alloc&>().allocate_at_least(std::declval<Args>()...))>; | |
template <typename Alloc, typename... Args> | |
using detect_is_deallocate_noexcept = std::integral_constant<bool, noexcept(std::declval<Alloc&>().deallocate(std::declval<Args>()...))>; | |
template <typename Alloc, typename... Args> | |
using detect_is_construct_noexcept = std::integral_constant<bool, noexcept(std::declval<Alloc&>().construct(std::declval<Args>()...))>; | |
template <typename Alloc, typename... Args> | |
using detect_allocate = decltype(std::declval<Alloc&>().allocate(std::declval<Args>()...)); | |
template <typename Alloc, typename... Args> | |
using detect_allocate_at_least = decltype(std::declval<Alloc&>().allocate_at_least(std::declval<Args>()...)); | |
template <typename Alloc, typename... Args> | |
using detect_deallocate = decltype(std::declval<Alloc&>().deallocate(std::declval<Args>()...)); | |
template <typename Alloc, typename... Args> | |
using detect_construct = decltype(std::declval<Alloc&>().construct(std::declval<Args>()...)); | |
template <typename Alloc, typename... Args> | |
using detect_destroy = decltype(std::declval<Alloc&>().destroy(std::declval<Args>()...)); | |
template <typename Alloc, typename... Args> | |
using detect_expand = decltype(std::declval<Alloc&>().expand(std::declval<Args>()...)); | |
template <typename Alloc, typename... Args> | |
using detect_shrink = decltype(std::declval<Alloc&>().shrink(std::declval<Args>()...)); | |
template <typename Alloc, typename... Args> | |
using detect_max_size = decltype(std::declval<Alloc&>().max_size(std::declval<Args>()...)); | |
template <typename Alloc, typename... Args> | |
using detect_select_on_container_copy_construction = decltype(std::declval<Alloc&>().select_on_container_copy_construction(std::declval<Args>()...)); | |
template <typename Alloc, typename... Args> | |
using detect_select_on_container_move_construction = decltype(std::declval<Alloc&>().select_on_container_move_construction(std::declval<Args>()...)); | |
} | |
struct indeterminate_t {} inline constexpr indeterminate{}; | |
template <typename Pointer, typename SizeType> | |
struct allocation { | |
Pointer memory; | |
SizeType number_of_elements; | |
}; | |
template <typename Alloc> | |
using allocation_of = allocation< | |
detected_or<typename Alloc::value_type*, detail::alloc_pointer, Alloc>, | |
detected_or<std::size_t, detail::alloc_size_type, Alloc> | |
>; | |
template <typename Alloc> | |
class allocator_access { | |
private: | |
using old_traits_type = std::allocator_traits<Alloc>; | |
public: | |
using allocator_type = Alloc; | |
using allocation_type = allocation_of<allocator_type>; | |
using value_type = typename allocator_type::value_type; | |
using pointer = detected_or<value_type*, detail::alloc_pointer, Alloc>; | |
using const_pointer = detected_or<const value_type*, detail::alloc_const_pointer, Alloc>; | |
using void_pointer = detected_or<void*, detail::alloc_void_pointer, Alloc>; | |
using const_void_pointer = detected_or<const void*, detail::alloc_const_void_pointer, Alloc>; | |
using size_type = detected_or<std::size_t, detail::alloc_size_type, Alloc>; | |
using difference_type = detected_or<std::ptrdiff_t, detail::alloc_difference_type, Alloc>; | |
using is_always_equal = detected_or<typename std::is_empty<Alloc>::type, detail::alloc_is_always_equal, Alloc>; | |
using propagate_on_container_copy_assignment = detected_or<std::false_type, detail::alloc_propagate_on_container_copy_assignment, Alloc>; | |
using propagate_on_container_move_assignment = detected_or<std::false_type, detail::alloc_propagate_on_container_move_assignment, Alloc>; | |
using propagate_on_container_swap = detected_or<std::false_type, detail::alloc_propagate_on_container_swap, Alloc>; | |
template <typename OtherT> | |
using rebind_alloc = detected_or< | |
typename detail::manually_rebound_allocator<OtherT, allocator_type>::type, | |
detail::alloc_rebind_alloc, Alloc, OtherT | |
>; | |
template <typename OtherT> | |
using rebind_access = allocator_access<rebind_alloc<OtherT>>; | |
private: | |
template <typename... Args> | |
inline static constexpr bool is_construct_noexcept_v = detected_or_v<std::integral_constant<bool, std::is_nothrow_constructible_v<value_type, Args...>>, detail::detect_is_construct_noexcept, allocator_type, Args...>; | |
inline static constexpr bool is_allocate_noexcept_v = is_detected_v<detail::detect_is_allocate_noexcept, allocator_type, size_type>; | |
inline static constexpr bool is_allocate_with_hint_noexcept_v = is_detected_v<detail::detect_is_allocate_noexcept, allocator_type, size_type, const_void_pointer>; | |
inline static constexpr bool is_allocate_at_least_noexcept_v = is_detected_v<detail::detect_is_allocate_noexcept, allocator_type, size_type>; | |
inline static constexpr bool is_allocate_at_least_with_hint_noexcept_v = is_detected_v<detail::detect_is_allocate_noexcept, allocator_type, size_type, const_void_pointer>; | |
inline static constexpr bool is_deallocate_noexcept_v = is_detected_v<detail::detect_is_deallocate_noexcept, allocator_type, pointer, size_type>; | |
}; | |
} // std0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <type_traits> | |
namespace std0 { | |
namespace detail { | |
template <typename T, template <typename...> class Templ> | |
struct is_specialization_of : std::false_type {}; | |
template <typename... T, template <typename...> class Templ> | |
struct is_specialization_of<Templ<T...>, Templ> : std::true_type {}; | |
} | |
struct none_such {}; | |
template <typename DefaultType, | |
template <typename...> typename Operation, typename... Args> | |
struct detector { | |
using value_type = std::false_type; | |
using type = DefaultType; | |
}; | |
template <typename DefaultType, | |
template <typename...> typename Operation, typename... Args> | |
requires requires { typename Operation<Args...>; } | |
struct detector<DefaultType, Operation, Args...> { | |
using value_type = std::true_type; | |
using type = Operation<Args...>; | |
}; | |
template <template <typename...> typename Operation, typename... Args> | |
using is_detected = typename detector<none_such, Operation, Args...>::value_type; | |
template <template <typename...> typename Operation, typename... Args> | |
inline constexpr bool is_detected_v = is_detected<Operation, Args...>::value; | |
template <template <typename...> typename Operation, typename... Args> | |
using detected_t = typename detector<none_such, Operation, Args...>::type; | |
template <typename DefaultType, template <typename...> typename Operation, typename... Args> | |
using detected_or = typename detector<DefaultType, Operation, Args...>::type; | |
template <typename DefaultType, template <typename...> typename Operation, typename... Args> | |
inline constexpr auto detected_or_v = detected_or<DefaultType, Operation, Args...>::value; | |
template <typename T, template <typename...> class Templ> | |
using is_specialization_of = std::bool_constant<detail::is_specialization_of<std::remove_cv_t<T>, Templ>::value>; | |
template <typename T, template <typename...> class Templ> | |
inline constexpr bool is_specialization_of_v = is_specialization_of<std::remove_cv_t<T>, Templ>::value; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment