Skip to content

Instantly share code, notes, and snippets.

@ThePhD
Created May 18, 2020 03:12
Show Gist options
  • Save ThePhD/27ef91a6820e7d5c8bc8022cebfb0d29 to your computer and use it in GitHub Desktop.
Save ThePhD/27ef91a6820e7d5c8bc8022cebfb0d29 to your computer and use it in GitHub Desktop.
#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
#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