Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions source/tinystl/experimental/type_traits.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#pragma once

#include "tinystl/type_traits/integral_constant.h"
#include "tinystl/type_traits/void_t.h"
#include "tinystl/type_traits/is_same.h"
#include "tinystl/type_traits/is_convertible.h"

namespace detail {
template <
class Default, class AlwaysVoid, template <class...> class Op, class... Args>
struct detector {
using value_t = tinystl::false_type;
using type = Default;
};

template <class Default, template <class...> class Op, class... Args>
struct detector<Default, tinystl::void_t<Op<Args...>>, Op, Args...> {
using value_t = tinystl::true_type;
using type = Op<Args...>;
};
} // namespace detail

namespace tinystl {

struct nonesuch {
~nonesuch() = delete;
nonesuch(nonesuch const &) = delete;
void operator=(nonesuch const &) = delete;
};

template <template <class...> class Op, class... Args>
using is_detected =
typename detail::detector<nonesuch, void, Op, Args...>::value_t;

template <template <class...> class Op, class... Args>
using detected_t = typename detail::detector<nonesuch, void, Op, Args...>::type;

template <class Default, template <class...> class Op, class... Args>
using detected_or = detail::detector<Default, void, Op, Args...>;

template< template<class...> class Op, class... Args >
constexpr inline bool is_detected_v = is_detected<Op, Args...>::value;

template< class Default, template<class...> class Op, class... Args >
using detected_or_t = typename detected_or<Default, Op, Args...>::type;

template< class Expected, template<class...> class Op, class... Args >
using is_detected_exact = is_same<Expected, detected_t<Op, Args...>>;

template< class Expected, template<class...> class Op, class... Args >
constexpr inline bool is_detected_exact_v =
is_detected_exact<Expected, Op, Args...>::value;

template< class To, template<class...> class Op, class... Args >
using is_detected_convertible =
is_convertible<detected_t<Op, Args...>, To>;

template< class To, template<class...> class Op, class... Args >
constexpr inline bool is_detected_convertible_v =
is_detected_convertible<To, Op, Args...>::value;

} // namespace tinystl
3 changes: 3 additions & 0 deletions source/tinystl/type_traits.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#pragma once

// https://en.cppreference.com/w/cpp/header/type_traits.html
// https://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html
// https://clang.llvm.org/docs/LanguageExtensions.html#type-trait-primitives
// https://learn.microsoft.com/en-us/cpp/extensions/compiler-support-for-type-traits-cpp-component-extensions?view=msvc-170

// composite_type_categories
#include <tinystl/type_traits/is_arithmetic.h>
Expand Down
35 changes: 35 additions & 0 deletions source/tinystl/type_traits/add_reference.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#pragma once

#include "tinystl/type_traits/void_t.h"

namespace tinystl {

template <class _Ty, class = void>
struct _Add_reference { // add reference (non-referenceable type)
using _Lvalue = _Ty;
using _Rvalue = _Ty;
};

template <class _Ty>
struct _Add_reference<_Ty, void_t<_Ty&>> { // (referenceable type)
using _Lvalue = _Ty&;
using _Rvalue = _Ty&&;
};

template <class _Ty>
struct add_lvalue_reference {
using type = typename _Add_reference<_Ty>::_Lvalue;
};

template <class _Ty>
using add_lvalue_reference_t = typename _Add_reference<_Ty>::_Lvalue;

template <class _Ty>
struct add_rvalue_reference {
using type = typename _Add_reference<_Ty>::_Rvalue;
};

template <class _Ty>
using add_rvalue_reference_t = typename _Add_reference<_Ty>::_Rvalue;

} // namespace tinystl
38 changes: 38 additions & 0 deletions source/tinystl/type_traits/is_constructible.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#pragma once

#include "tinystl/type_traits/add_reference.h"
#include "tinystl/type_traits/integral_constant.h"


namespace tinystl {

template <class _Tp, class... _Args>
struct is_constructible : bool_constant<__is_constructible(_Tp, _Args...)> {};

template <class _Tp, class... _Args>
inline constexpr bool is_constructible_v = __is_constructible(_Tp, _Args...);

template <class _Tp>
struct is_copy_constructible
: bool_constant<__is_constructible(_Tp, add_lvalue_reference_t<const _Tp>)> {
};

template <class _Tp>
inline constexpr bool is_copy_constructible_v =
is_copy_constructible<_Tp>::value;

template <class _Tp>
struct is_move_constructible
: bool_constant<__is_constructible(_Tp, add_rvalue_reference_t<_Tp>)> {};

template <class _Tp>
inline constexpr bool is_move_constructible_v =
is_move_constructible<_Tp>::value;

template <class _Tp>
struct is_default_constructible : bool_constant<__is_constructible(_Tp)> {};

template <class _Tp>
inline constexpr bool is_default_constructible_v = __is_constructible(_Tp);

} // namespace tinystl
21 changes: 21 additions & 0 deletions source/tinystl/type_traits/is_convertible.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#pragma once

#include "tinystl/type_traits/integral_constant.h"

namespace tinystl {

template <class _T1, class _T2>
struct is_convertible : bool_constant<__is_convertible(_T1, _T2)> {};

template <class _From, class _To>
inline constexpr bool is_convertible_v = __is_convertible(_From, _To);

template <class _Tp, class _Up>
struct is_nothrow_convertible
: bool_constant<__is_nothrow_convertible(_Tp, _Up)> {};

template <class _Tp, class _Up>
inline constexpr bool is_nothrow_convertible_v =
__is_nothrow_convertible(_Tp, _Up);

} // namespace tinystl
2 changes: 1 addition & 1 deletion source/tinystl/type_traits/is_empty.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ template <class T>
struct is_empty : bool_constant<__is_empty(T)> {};

template <class T>
inline constexpr bool is_empty_v = is_empty<T>::value;
inline constexpr bool is_empty_v = __is_empty(T);
} // namespace tinystl
2 changes: 1 addition & 1 deletion source/tinystl/type_traits/is_enum.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ template <class T>
struct is_enum : tinystl::bool_constant<__is_enum(T)> {};

template <class T>
inline constexpr bool is_enum_v = is_enum<T>::value;
inline constexpr bool is_enum_v = __is_enum(T);

} // namespace tinystl
Loading