diff --git a/.clang-tidy b/.clang-tidy new file mode 100644 index 0000000..9b373bf --- /dev/null +++ b/.clang-tidy @@ -0,0 +1,9 @@ +Checks: > + modernize-use-this + +WarningsAsErrors: modernize-use-this + +CheckOptions: + - key: modernize-use-this.UseThis + value: true + diff --git a/.gitignore b/.gitignore index 259148f..4df42a0 100644 --- a/.gitignore +++ b/.gitignore @@ -30,3 +30,8 @@ *.exe *.out *.app + +/llvm/ +.cache/clangd/index +compile_commands.json +test/.cache/clangd/index diff --git a/Makefile b/Makefile index fbd5b5a..138cb31 100644 --- a/Makefile +++ b/Makefile @@ -1,40 +1,37 @@ -BIN=YOUR_PROJECT_NAME +LIB=libc+ -CC_FLAGS = -Isrc/include -std=c23 -CXX_FLAGS = -Isrc/include -Ilib/ -std=c++23 -LD_FLAGS = -lm +COM_FLAGS = -fPIC -Isrc/include +CC_FLAGS = -std=c23 +CXX_FLAGS = -std=c++23 -nostdinc++ +LD_FLAGS = -nostdlib++ -lsupc++ CC=gcc CXX=g++ -LD=gcc +LD=g++ AR=ar -LIBS= -include lib/make.mk - cxx_sources=$(wildcard src/*.cpp) c_sources=$(wildcard src/*.c) -objects=$(patsubst src/%.cpp,build/obj/%.cpp.o,$(cxx_sources)) $(patsubst src/%.c,build/obj/%.c.o,$(c_sources)) $(LIBS) +objects=$(patsubst src/%.cpp,build/obj/%.cpp.o,$(cxx_sources)) $(patsubst src/%.c,build/obj/%.c.o,$(c_sources)) -all: build/$(BIN) compile_commands.json - @rm -r build/obj - -keep: build/$(BIN) +all: build/$(LIB).a build/$(LIB).so compile_commands.json + +build/$(LIB).a: $(objects) + $(AR) rcs $@ $^ + +build/$(LIB).so: $(objects) + $(LD) -shared -o $@ $^ clean: rm -r build/obj/ - -build/$(BIN): $(objects) - $(LD) -o $@ $^ $(LD_FLAGS) - build/obj/%.cpp.o: */%.cpp @mkdir -p $(dir $@) - $(CXX) -c -o $@ $< $(CXX_FLAGS) + $(CXX) -c -o $@ $< $(CXX_FLAGS) $(COM_FLAGS) build/obj/%.c.o: */%.c @mkdir -p $(dir $@) - $(CC) -c -o $@ $< $(CC_FLAGS) + $(CC) -c -o $@ $< $(CC_FLAGS) $(COM_FLAGS) compile_commands.json: compiledb -n make diff --git a/lib/make.mk b/lib/make.mk deleted file mode 100644 index dea842a..0000000 --- a/lib/make.mk +++ /dev/null @@ -1,23 +0,0 @@ - - -#? Sample library build recipe: -#? Prefferably put this in the lib directory - -#? The onlu thing needed for root makefile, you can build it another way if u want -# LIBS += bin/lib/libmc.a -# -# libmc_src = $(wildcard lib/libmc/src/*.c) -# libmc_obj = $(patsubst lib/libmc/src/%.c,bin/lib/libmc/%.c.o,$(libmc_src)) -# -# bin/lib/libmc.a: $(libmc_obj) -# @mkdir -p $(dir $@) -# ar rcs $@ $^ -# -# bin/lib/libmc/%.c.o: lib/libmc/src/%.c -# @mkdir -p $(dir $@) -# $(CC) -c -o $@ $< - - - - - diff --git a/src/collections/vec.cpp b/src/collections/vec.cpp new file mode 100644 index 0000000..fe4f3cc --- /dev/null +++ b/src/collections/vec.cpp @@ -0,0 +1,65 @@ +#include +#include +#include +#include + +template +Option Vec::nth(const size_t n) { + if (this->count <= n) { + return Option(); + } + return Option(this->items[n]); +} + +template +Option Vec::nth(const size_t n) const { + if (this->count <= n) { + return Option(); + } + return Option(this->items[n]); +} + +template +Option Vec::pop() { + if (this->count == 0) { + return Option(); + } + + T popped = stl::move(this->items[--this->count]); + return Option(popped); +} + +template +void Vec::push(const T& val) { + if (this->capacity <= this->count) { + this->reserve(this->capacity * 2); + } + this->items[this->count++] = stl::move(val); +} + +template +void Vec::push(T&& val) {} + +template +Result Vec::reserve(size_t new_cap) { + if (new_cap <= this->capacity) { + return Result::err("New capacity is lower than current capacity"); + } + + T* new_data = (T*)(::operator new(sizeof(T) * new_cap)); + for (size_t i = 0; i < this->count; ++i) { + new (new_data + i) T(stl::move(this->items[i])); + } + + for (size_t i = 0; i < this->count; ++i) { + this->items[i].~T(); + } + + ::operator delete(this->items); + this->items = new_data; + this->capacity = new_cap; + return Result::ok(); +} + +template +void Vec::clear() {} \ No newline at end of file diff --git a/src/include/__type_traits/add_cv_quals.h b/src/include/__type_traits/add_cv_quals.h new file mode 100644 index 0000000..6c27f68 --- /dev/null +++ b/src/include/__type_traits/add_cv_quals.h @@ -0,0 +1,52 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_ADD_CV_H +#define _LIBCPP___TYPE_TRAITS_ADD_CV_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +struct _LIBCPP_NO_SPECIALIZATIONS add_const { + using type _LIBCPP_NODEBUG = const _Tp; +}; + +#if _LIBCPP_STD_VER >= 14 +template +using add_const_t = typename add_const<_Tp>::type; +#endif + +template +struct _LIBCPP_NO_SPECIALIZATIONS add_cv { + using type _LIBCPP_NODEBUG = const volatile _Tp; +}; + +#if _LIBCPP_STD_VER >= 14 +template +using add_cv_t = typename add_cv<_Tp>::type; +#endif + +template +struct _LIBCPP_NO_SPECIALIZATIONS add_volatile { + using type _LIBCPP_NODEBUG = volatile _Tp; +}; + +#if _LIBCPP_STD_VER >= 14 +template +using add_volatile_t = typename add_volatile<_Tp>::type; +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_ADD_CV_H diff --git a/src/include/__type_traits/add_lvalue_reference.h b/src/include/__type_traits/add_lvalue_reference.h new file mode 100644 index 0000000..5e65477 --- /dev/null +++ b/src/include/__type_traits/add_lvalue_reference.h @@ -0,0 +1,54 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_ADD_LVALUE_REFERENCE_H +#define _LIBCPP___TYPE_TRAITS_ADD_LVALUE_REFERENCE_H + +#include <__config> +#include <__type_traits/is_referenceable.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if __has_builtin(__add_lvalue_reference) + +template +using __add_lvalue_reference_t _LIBCPP_NODEBUG = __add_lvalue_reference(_Tp); + +#else + +template > +struct __add_lvalue_reference_impl { + using type _LIBCPP_NODEBUG = _Tp; +}; +template +struct __add_lvalue_reference_impl<_Tp, true> { + using type _LIBCPP_NODEBUG = _Tp&; +}; + +template +using __add_lvalue_reference_t = typename __add_lvalue_reference_impl<_Tp>::type; + +#endif // __has_builtin(__add_lvalue_reference) + +template +struct _LIBCPP_NO_SPECIALIZATIONS add_lvalue_reference { + using type _LIBCPP_NODEBUG = __add_lvalue_reference_t<_Tp>; +}; + +#if _LIBCPP_STD_VER >= 14 +template +using add_lvalue_reference_t = __add_lvalue_reference_t<_Tp>; +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_ADD_LVALUE_REFERENCE_H diff --git a/src/include/__type_traits/add_pointer.h b/src/include/__type_traits/add_pointer.h new file mode 100644 index 0000000..a9a51b8 --- /dev/null +++ b/src/include/__type_traits/add_pointer.h @@ -0,0 +1,55 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_ADD_POINTER_H +#define _LIBCPP___TYPE_TRAITS_ADD_POINTER_H + +#include <__config> +#include <__type_traits/is_referenceable.h> +#include <__type_traits/is_void.h> +#include <__type_traits/remove_reference.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_WORKAROUND_OBJCXX_COMPILER_INTRINSICS) && __has_builtin(__add_pointer) + +template +using __add_pointer_t _LIBCPP_NODEBUG = __add_pointer(_Tp); + +#else +template || is_void<_Tp>::value> +struct __add_pointer_impl { + using type _LIBCPP_NODEBUG = __libcpp_remove_reference_t<_Tp>*; +}; +template +struct __add_pointer_impl<_Tp, false> { + using type _LIBCPP_NODEBUG = _Tp; +}; + +template +using __add_pointer_t = typename __add_pointer_impl<_Tp>::type; + +#endif // !defined(_LIBCPP_WORKAROUND_OBJCXX_COMPILER_INTRINSICS) && __has_builtin(__add_pointer) + +template +struct _LIBCPP_NO_SPECIALIZATIONS add_pointer { + using type _LIBCPP_NODEBUG = __add_pointer_t<_Tp>; +}; + +#if _LIBCPP_STD_VER >= 14 +template +using add_pointer_t = __add_pointer_t<_Tp>; +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_ADD_POINTER_H diff --git a/src/include/__type_traits/add_rvalue_reference.h b/src/include/__type_traits/add_rvalue_reference.h new file mode 100644 index 0000000..c51dd54 --- /dev/null +++ b/src/include/__type_traits/add_rvalue_reference.h @@ -0,0 +1,54 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_ADD_RVALUE_REFERENCE_H +#define _LIBCPP___TYPE_TRAITS_ADD_RVALUE_REFERENCE_H + +#include <__config> +#include <__type_traits/is_referenceable.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if __has_builtin(__add_rvalue_reference) + +template +using __add_rvalue_reference_t _LIBCPP_NODEBUG = __add_rvalue_reference(_Tp); + +#else + +template > +struct __add_rvalue_reference_impl { + using type _LIBCPP_NODEBUG = _Tp; +}; +template +struct __add_rvalue_reference_impl<_Tp, true> { + using type _LIBCPP_NODEBUG = _Tp&&; +}; + +template +using __add_rvalue_reference_t = typename __add_rvalue_reference_impl<_Tp>::type; + +#endif // __has_builtin(__add_rvalue_reference) + +template +struct _LIBCPP_NO_SPECIALIZATIONS add_rvalue_reference { + using type _LIBCPP_NODEBUG = __add_rvalue_reference_t<_Tp>; +}; + +#if _LIBCPP_STD_VER >= 14 +template +using add_rvalue_reference_t = __add_rvalue_reference_t<_Tp>; +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_ADD_RVALUE_REFERENCE_H diff --git a/src/include/__type_traits/aligned_storage.h b/src/include/__type_traits/aligned_storage.h new file mode 100644 index 0000000..5c2208a --- /dev/null +++ b/src/include/__type_traits/aligned_storage.h @@ -0,0 +1,88 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_ALIGNED_STORAGE_H +#define _LIBCPP___TYPE_TRAITS_ALIGNED_STORAGE_H + +#include <__config> +#include <__cstddef/size_t.h> +#include <__type_traits/integral_constant.h> +#include <__type_traits/type_list.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +struct __align_type { + static const size_t value = _LIBCPP_PREFERRED_ALIGNOF(_Tp); + typedef _Tp type; +}; + +struct __struct_double { + long double __lx; +}; +struct __struct_double4 { + double __lx[4]; +}; + +using __all_types _LIBCPP_NODEBUG = + __type_list<__align_type, + __align_type, + __align_type, + __align_type, + __align_type, + __align_type, + __align_type, + __align_type<__struct_double>, + __align_type<__struct_double4>, + __align_type >; + +template +struct __find_max_align; + +template +struct __find_max_align<__type_list<_Head>, _Len> : public integral_constant {}; + +template +struct __select_align { +private: + static const size_t __min = _A2 < _A1 ? _A2 : _A1; + static const size_t __max = _A1 < _A2 ? _A2 : _A1; + +public: + static const size_t value = _Len < __max ? __min : __max; +}; + +template +struct __find_max_align<__type_list<_Head, _Tail...>, _Len> + : public integral_constant< + size_t, + __select_align<_Len, _Head::value, __find_max_align<__type_list<_Tail...>, _Len>::value>::value> {}; + +template ::value> +struct _LIBCPP_DEPRECATED_IN_CXX23 _LIBCPP_NO_SPECIALIZATIONS aligned_storage { + union _ALIGNAS(_Align) type { + unsigned char __data[(_Len + _Align - 1) / _Align * _Align]; + }; +}; + +#if _LIBCPP_STD_VER >= 14 + +_LIBCPP_SUPPRESS_DEPRECATED_PUSH +template ::value> +using aligned_storage_t _LIBCPP_DEPRECATED_IN_CXX23 = typename aligned_storage<_Len, _Align>::type; +_LIBCPP_SUPPRESS_DEPRECATED_POP + +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_ALIGNED_STORAGE_H diff --git a/src/include/__type_traits/aligned_union.h b/src/include/__type_traits/aligned_union.h new file mode 100644 index 0000000..1223dc2 --- /dev/null +++ b/src/include/__type_traits/aligned_union.h @@ -0,0 +1,50 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_ALIGNED_UNION_H +#define _LIBCPP___TYPE_TRAITS_ALIGNED_UNION_H + +#include <__config> +#include <__cstddef/size_t.h> +#include <__type_traits/aligned_storage.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +struct __static_max; + +template +struct __static_max<_I0> { + static const size_t value = _I0; +}; + +template +struct __static_max<_I0, _I1, _In...> { + static const size_t value = _I0 >= _I1 ? __static_max<_I0, _In...>::value : __static_max<_I1, _In...>::value; +}; + +template +struct _LIBCPP_DEPRECATED_IN_CXX23 _LIBCPP_NO_SPECIALIZATIONS aligned_union { + static const size_t alignment_value = + __static_max<_LIBCPP_PREFERRED_ALIGNOF(_Type0), _LIBCPP_PREFERRED_ALIGNOF(_Types)...>::value; + static const size_t __len = __static_max<_Len, sizeof(_Type0), sizeof(_Types)...>::value; + typedef typename aligned_storage<__len, alignment_value>::type type; +}; + +#if _LIBCPP_STD_VER >= 14 +template +using aligned_union_t _LIBCPP_DEPRECATED_IN_CXX23 = typename aligned_union<_Len, _Types...>::type; +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_ALIGNED_UNION_H diff --git a/src/include/__type_traits/alignment_of.h b/src/include/__type_traits/alignment_of.h new file mode 100644 index 0000000..2a74094 --- /dev/null +++ b/src/include/__type_traits/alignment_of.h @@ -0,0 +1,32 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_ALIGNMENT_OF_H +#define _LIBCPP___TYPE_TRAITS_ALIGNMENT_OF_H + +#include <__config> +#include <__cstddef/size_t.h> +#include <__type_traits/integral_constant.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +struct _LIBCPP_NO_SPECIALIZATIONS alignment_of : public integral_constant {}; + +#if _LIBCPP_STD_VER >= 17 +template +_LIBCPP_NO_SPECIALIZATIONS inline constexpr size_t alignment_of_v = _LIBCPP_ALIGNOF(_Tp); +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_ALIGNMENT_OF_H diff --git a/src/include/__type_traits/can_extract_key.h b/src/include/__type_traits/can_extract_key.h new file mode 100644 index 0000000..b8359d0 --- /dev/null +++ b/src/include/__type_traits/can_extract_key.h @@ -0,0 +1,53 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_CAN_EXTRACT_KEY_H +#define _LIBCPP___TYPE_TRAITS_CAN_EXTRACT_KEY_H + +#include <__config> +#include <__fwd/pair.h> +#include <__type_traits/conditional.h> +#include <__type_traits/integral_constant.h> +#include <__type_traits/is_same.h> +#include <__type_traits/remove_const.h> +#include <__type_traits/remove_const_ref.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +// These traits are used in __tree and __hash_table +struct __extract_key_fail_tag {}; +struct __extract_key_self_tag {}; +struct __extract_key_first_tag {}; + +template > +struct __can_extract_key + : __conditional_t<_IsSame<_RawValTy, _Key>::value, __extract_key_self_tag, __extract_key_fail_tag> {}; + +template +struct __can_extract_key<_Pair, _Key, pair<_First, _Second> > + : __conditional_t<_IsSame<__remove_const_t<_First>, _Key>::value, __extract_key_first_tag, __extract_key_fail_tag> { +}; + +// __can_extract_map_key uses true_type/false_type instead of the tags. +// It returns true if _Key != _ContainerValueTy (the container is a map not a set) +// and _ValTy == _Key. +template > +struct __can_extract_map_key : integral_constant::value> {}; + +// This specialization returns __extract_key_fail_tag for non-map containers +// because _Key == _ContainerValueTy +template +struct __can_extract_map_key<_ValTy, _Key, _Key, _RawValTy> : false_type {}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_CAN_EXTRACT_KEY_H diff --git a/src/include/__type_traits/common_reference.h b/src/include/__type_traits/common_reference.h new file mode 100644 index 0000000..c27da52 --- /dev/null +++ b/src/include/__type_traits/common_reference.h @@ -0,0 +1,192 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_COMMON_REFERENCE_H +#define _LIBCPP___TYPE_TRAITS_COMMON_REFERENCE_H + +#include <__config> +#include <__type_traits/common_type.h> +#include <__type_traits/copy_cv.h> +#include <__type_traits/copy_cvref.h> +#include <__type_traits/is_convertible.h> +#include <__type_traits/is_reference.h> +#include <__type_traits/remove_cvref.h> +#include <__type_traits/remove_reference.h> +#include <__utility/declval.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +// common_reference +#if _LIBCPP_STD_VER >= 20 +// Let COND_RES(X, Y) be: +template +using __cond_res _LIBCPP_NODEBUG = decltype(false ? std::declval<_Xp (&)()>()() : std::declval<_Yp (&)()>()()); + +// Let `XREF(A)` denote a unary alias template `T` such that `T` denotes the same type as `U` +// with the addition of `A`'s cv and reference qualifiers, for a non-reference cv-unqualified type +// `U`. +// [Note: `XREF(A)` is `__xref::template __apply`] +template +struct __xref { + template + using __apply _LIBCPP_NODEBUG = __copy_cvref_t<_Tp, _Up>; +}; + +// Given types A and B, let X be remove_reference_t, let Y be remove_reference_t, +// and let COMMON-REF(A, B) be: +template , class _Yp = remove_reference_t<_Bp>> +struct __common_ref; + +template +using __common_ref_t _LIBCPP_NODEBUG = typename __common_ref<_Xp, _Yp>::__type; + +template +using __cv_cond_res _LIBCPP_NODEBUG = __cond_res<__copy_cv_t<_Xp, _Yp>&, __copy_cv_t<_Yp, _Xp>&>; + +// If A and B are both lvalue reference types, COMMON-REF(A, B) is +// COND-RES(COPYCV(X, Y)&, COPYCV(Y, X)&) if that type exists and is a reference type. +// clang-format off +template + requires + requires { typename __cv_cond_res<_Xp, _Yp>; } && + is_reference_v<__cv_cond_res<_Xp, _Yp>> +struct __common_ref<_Ap&, _Bp&, _Xp, _Yp> { + using __type _LIBCPP_NODEBUG = __cv_cond_res<_Xp, _Yp>; +}; +// clang-format on + +// Otherwise, let C be remove_reference_t&&. ... +template +using __common_ref_C _LIBCPP_NODEBUG = remove_reference_t<__common_ref_t<_Xp&, _Yp&>>&&; + +// .... If A and B are both rvalue reference types, C is well-formed, and +// is_convertible_v && is_convertible_v is true, then COMMON-REF(A, B) is C. +// clang-format off +template + requires + requires { typename __common_ref_C<_Xp, _Yp>; } && + is_convertible_v<_Ap&&, __common_ref_C<_Xp, _Yp>> && + is_convertible_v<_Bp&&, __common_ref_C<_Xp, _Yp>> +struct __common_ref<_Ap&&, _Bp&&, _Xp, _Yp> { + using __type _LIBCPP_NODEBUG = __common_ref_C<_Xp, _Yp>; +}; +// clang-format on + +// Otherwise, let D be COMMON-REF(const X&, Y&). ... +template +using __common_ref_D _LIBCPP_NODEBUG = __common_ref_t; + +// ... If A is an rvalue reference and B is an lvalue reference and D is well-formed and +// is_convertible_v is true, then COMMON-REF(A, B) is D. +// clang-format off +template + requires + requires { typename __common_ref_D<_Xp, _Yp>; } && + is_convertible_v<_Ap&&, __common_ref_D<_Xp, _Yp>> +struct __common_ref<_Ap&&, _Bp&, _Xp, _Yp> { + using __type _LIBCPP_NODEBUG = __common_ref_D<_Xp, _Yp>; +}; +// clang-format on + +// Otherwise, if A is an lvalue reference and B is an rvalue reference, then +// COMMON-REF(A, B) is COMMON-REF(B, A). +template +struct __common_ref<_Ap&, _Bp&&, _Xp, _Yp> : __common_ref<_Bp&&, _Ap&> {}; + +// Otherwise, COMMON-REF(A, B) is ill-formed. +template +struct __common_ref {}; + +// Note C: For the common_reference trait applied to a parameter pack [...] + +template +struct common_reference; + +template +using common_reference_t = typename common_reference<_Types...>::type; + +// bullet 1 - sizeof...(T) == 0 +template <> +struct common_reference<> {}; + +// bullet 2 - sizeof...(T) == 1 +template +struct common_reference<_Tp> { + using type _LIBCPP_NODEBUG = _Tp; +}; + +// bullet 3 - sizeof...(T) == 2 +template +struct __common_reference_sub_bullet3; +template +struct __common_reference_sub_bullet2 : __common_reference_sub_bullet3<_Tp, _Up> {}; +template +struct __common_reference_sub_bullet1 : __common_reference_sub_bullet2<_Tp, _Up> {}; + +// sub-bullet 1 - If T1 and T2 are reference types and COMMON-REF(T1, T2) is well-formed, then +// the member typedef `type` denotes that type. +template +struct common_reference<_Tp, _Up> : __common_reference_sub_bullet1<_Tp, _Up> {}; + +template + requires is_reference_v<_Tp> && is_reference_v<_Up> && requires { typename __common_ref_t<_Tp, _Up>; } +struct __common_reference_sub_bullet1<_Tp, _Up> { + using type _LIBCPP_NODEBUG = __common_ref_t<_Tp, _Up>; +}; + +// sub-bullet 2 - Otherwise, if basic_common_reference, remove_cvref_t, XREF(T1), XREF(T2)>::type +// is well-formed, then the member typedef `type` denotes that type. +template class, template class> +struct basic_common_reference {}; + +template +using __basic_common_reference_t _LIBCPP_NODEBUG = + typename basic_common_reference, + remove_cvref_t<_Up>, + __xref<_Tp>::template __apply, + __xref<_Up>::template __apply>::type; + +template + requires requires { typename __basic_common_reference_t<_Tp, _Up>; } +struct __common_reference_sub_bullet2<_Tp, _Up> { + using type _LIBCPP_NODEBUG = __basic_common_reference_t<_Tp, _Up>; +}; + +// sub-bullet 3 - Otherwise, if COND-RES(T1, T2) is well-formed, +// then the member typedef `type` denotes that type. +template + requires requires { typename __cond_res<_Tp, _Up>; } +struct __common_reference_sub_bullet3<_Tp, _Up> { + using type _LIBCPP_NODEBUG = __cond_res<_Tp, _Up>; +}; + +// sub-bullet 4 & 5 - Otherwise, if common_type_t is well-formed, +// then the member typedef `type` denotes that type. +// - Otherwise, there shall be no member `type`. +template +struct __common_reference_sub_bullet3 : common_type<_Tp, _Up> {}; + +// bullet 4 - If there is such a type `C`, the member typedef type shall denote the same type, if +// any, as `common_reference_t`. +template + requires requires { typename common_reference_t<_Tp, _Up>; } +struct common_reference<_Tp, _Up, _Vp, _Rest...> : common_reference, _Vp, _Rest...> {}; + +// bullet 5 - Otherwise, there shall be no member `type`. +template +struct common_reference {}; + +#endif // _LIBCPP_STD_VER >= 20 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_COMMON_REFERENCE_H diff --git a/src/include/__type_traits/common_type.h b/src/include/__type_traits/common_type.h new file mode 100644 index 0000000..5643ce0 --- /dev/null +++ b/src/include/__type_traits/common_type.h @@ -0,0 +1,117 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_COMMON_TYPE_H +#define _LIBCPP___TYPE_TRAITS_COMMON_TYPE_H + +#include <__config> +#include <__type_traits/conditional.h> +#include <__type_traits/decay.h> +#include <__type_traits/is_same.h> +#include <__type_traits/remove_cvref.h> +#include <__type_traits/type_identity.h> +#include <__type_traits/void_t.h> +#include <__utility/declval.h> +#include <__utility/empty.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if __has_builtin(__builtin_common_type) + +template +struct common_type; + +template +using __common_type_t _LIBCPP_NODEBUG = typename common_type<_Args...>::type; + +template +struct common_type : __builtin_common_type<__common_type_t, __type_identity, __empty, _Args...> {}; + +#else +# if _LIBCPP_STD_VER >= 20 +// Let COND_RES(X, Y) be: +template +using __cond_type _LIBCPP_NODEBUG = decltype(false ? std::declval<_Tp>() : std::declval<_Up>()); + +template +struct __common_type3 {}; + +// sub-bullet 4 - "if COND_RES(CREF(D1), CREF(D2)) denotes a type..." +template +struct __common_type3<_Tp, _Up, void_t<__cond_type>> { + using type _LIBCPP_NODEBUG = remove_cvref_t<__cond_type>; +}; + +template +struct __common_type2_imp : __common_type3<_Tp, _Up> {}; +# else +template +struct __common_type2_imp {}; +# endif + +// sub-bullet 3 - "if decay_t() : declval())> ..." +template +struct __common_type2_imp<_Tp, _Up, __void_t() : std::declval<_Up>())> > { + using type _LIBCPP_NODEBUG = __decay_t() : std::declval<_Up>())>; +}; + +template +struct __common_type_impl {}; + +template +struct __common_types; +template +struct common_type; + +template +struct __common_type_impl< __common_types<_Tp, _Up>, __void_t::type> > { + typedef typename common_type<_Tp, _Up>::type type; +}; + +template +struct __common_type_impl<__common_types<_Tp, _Up, _Vp, _Rest...>, __void_t::type> > + : __common_type_impl<__common_types::type, _Vp, _Rest...> > {}; + +// bullet 1 - sizeof...(Tp) == 0 + +template <> +struct common_type<> {}; + +// bullet 2 - sizeof...(Tp) == 1 + +template +struct common_type<_Tp> : public common_type<_Tp, _Tp> {}; + +// bullet 3 - sizeof...(Tp) == 2 + +// sub-bullet 1 - "If is_same_v is false or ..." +template +struct common_type<_Tp, _Up> + : __conditional_t<_IsSame<_Tp, __decay_t<_Tp> >::value && _IsSame<_Up, __decay_t<_Up> >::value, + __common_type2_imp<_Tp, _Up>, + common_type<__decay_t<_Tp>, __decay_t<_Up> > > {}; + +// bullet 4 - sizeof...(Tp) > 2 + +template +struct common_type<_Tp, _Up, _Vp, _Rest...> : __common_type_impl<__common_types<_Tp, _Up, _Vp, _Rest...> > {}; + +#endif + +#if _LIBCPP_STD_VER >= 14 +template +using common_type_t = typename common_type<_Tp...>::type; +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_COMMON_TYPE_H diff --git a/src/include/__type_traits/conditional.h b/src/include/__type_traits/conditional.h new file mode 100644 index 0000000..71882fb --- /dev/null +++ b/src/include/__type_traits/conditional.h @@ -0,0 +1,64 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_CONDITIONAL_H +#define _LIBCPP___TYPE_TRAITS_CONDITIONAL_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +struct _IfImpl; + +template <> +struct _IfImpl { + template + using _Select _LIBCPP_NODEBUG = _IfRes; +}; + +template <> +struct _IfImpl { + template + using _Select _LIBCPP_NODEBUG = _ElseRes; +}; + +template +using _If _LIBCPP_NODEBUG = typename _IfImpl<_Cond>::template _Select<_IfRes, _ElseRes>; + +template +struct _LIBCPP_NO_SPECIALIZATIONS conditional { + using type _LIBCPP_NODEBUG = _If; +}; + +_LIBCPP_DIAGNOSTIC_PUSH +#if __has_warning("-Winvalid-specialization") +_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Winvalid-specialization") +#endif +template +struct conditional { + using type _LIBCPP_NODEBUG = _Then; +}; +_LIBCPP_DIAGNOSTIC_POP + +#if _LIBCPP_STD_VER >= 14 +template +using conditional_t _LIBCPP_NODEBUG = typename conditional<_Bp, _IfRes, _ElseRes>::type; +#endif + +// Helper so we can use "conditional_t" in all language versions. +template +using __conditional_t _LIBCPP_NODEBUG = typename conditional<_Bp, _If, _Then>::type; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_CONDITIONAL_H diff --git a/src/include/__type_traits/conjunction.h b/src/include/__type_traits/conjunction.h new file mode 100644 index 0000000..ad9656a --- /dev/null +++ b/src/include/__type_traits/conjunction.h @@ -0,0 +1,70 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_CONJUNCTION_H +#define _LIBCPP___TYPE_TRAITS_CONJUNCTION_H + +#include <__config> +#include <__type_traits/conditional.h> +#include <__type_traits/enable_if.h> +#include <__type_traits/integral_constant.h> +#include <__type_traits/is_same.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +using __expand_to_true _LIBCPP_NODEBUG = true_type; + +template +__expand_to_true<__enable_if_t<_Pred::value>...> __and_helper(int); + +template +false_type __and_helper(...); + +// _And always performs lazy evaluation of its arguments. +// +// However, `_And<_Pred...>` itself will evaluate its result immediately (without having to +// be instantiated) since it is an alias, unlike `conjunction<_Pred...>`, which is a struct. +// If you want to defer the evaluation of `_And<_Pred...>` itself, use `_Lazy<_And, _Pred...>`. +template +using _And _LIBCPP_NODEBUG = decltype(std::__and_helper<_Pred...>(0)); + +template +struct __all_dummy; + +template +struct __all : _IsSame<__all_dummy<_Pred...>, __all_dummy<((void)_Pred, true)...> > {}; + +#if _LIBCPP_STD_VER >= 17 + +template +struct _LIBCPP_NO_SPECIALIZATIONS conjunction : true_type {}; + +_LIBCPP_DIAGNOSTIC_PUSH +# if __has_warning("-Winvalid-specialization") +_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Winvalid-specialization") +# endif +template +struct conjunction<_Arg> : _Arg {}; + +template +struct conjunction<_Arg, _Args...> : conditional_t> {}; +_LIBCPP_DIAGNOSTIC_POP + +template +_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool conjunction_v = conjunction<_Args...>::value; + +#endif // _LIBCPP_STD_VER >= 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_CONJUNCTION_H diff --git a/src/include/__type_traits/container_traits.h b/src/include/__type_traits/container_traits.h new file mode 100644 index 0000000..5262cef --- /dev/null +++ b/src/include/__type_traits/container_traits.h @@ -0,0 +1,43 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_CONTAINER_TRAITS_H +#define _LIBCPP___TYPE_TRAITS_CONTAINER_TRAITS_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +// // __container_traits is a general purpose utility containing traits describing various containers operations. +// It currently only has one trait: `__emplacement_has_strong_exception_safety_guarantee`, but it's +// intended to be extended in the future. +// +// These traits should only be used for optimization or QoI purposes. In particular, since this is a libc++ internal +// mechanism, no user-defined containers should be expected to specialize these traits (in fact it would be illegal for +// them to do so). Hence, when using these traits to implement something, make sure that a container that fails to +// specialize these traits does not result in non-conforming code. +// +// When a trait is nonsensical for a type, this class still provides a fallback value for that trait. +// For example, `std::array` does not support `insert` or `emplace`, so +// `__emplacement_has_strong_exception_safety_guarantee` is false for such types. +template +struct __container_traits { + // A trait that tells whether a single element insertion/emplacement via member function + // `insert(...)` or `emplace(...)` has strong exception guarantee, that is, if the function + // exits via an exception, the original container is unaffected + static _LIBCPP_CONSTEXPR const bool __emplacement_has_strong_exception_safety_guarantee = false; +}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_CONTAINER_TRAITS_H diff --git a/src/include/__type_traits/copy_cv.h b/src/include/__type_traits/copy_cv.h new file mode 100644 index 0000000..8378fbd --- /dev/null +++ b/src/include/__type_traits/copy_cv.h @@ -0,0 +1,51 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_COPY_CV_H +#define _LIBCPP___TYPE_TRAITS_COPY_CV_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +// Let COPYCV(FROM, TO) be an alias for type TO with the addition of FROM's +// top-level cv-qualifiers. +template +struct __copy_cv { + template + using __apply _LIBCPP_NODEBUG = _To; +}; + +template +struct __copy_cv { + template + using __apply _LIBCPP_NODEBUG = const _To; +}; + +template +struct __copy_cv { + template + using __apply _LIBCPP_NODEBUG = volatile _To; +}; + +template +struct __copy_cv { + template + using __apply _LIBCPP_NODEBUG = const volatile _To; +}; + +template +using __copy_cv_t _LIBCPP_NODEBUG = typename __copy_cv<_From>::template __apply<_To>; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_COPY_CV_H diff --git a/src/include/__type_traits/copy_cvref.h b/src/include/__type_traits/copy_cvref.h new file mode 100644 index 0000000..158e5a5 --- /dev/null +++ b/src/include/__type_traits/copy_cvref.h @@ -0,0 +1,46 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_COPY_CVREF_H +#define _LIBCPP___TYPE_TRAITS_COPY_CVREF_H + +#include <__config> +#include <__type_traits/add_lvalue_reference.h> +#include <__type_traits/add_rvalue_reference.h> +#include <__type_traits/copy_cv.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +struct __copy_cvref { + template + using __apply _LIBCPP_NODEBUG = __copy_cv_t<_From, _To>; +}; + +template +struct __copy_cvref<_From&> { + template + using __apply _LIBCPP_NODEBUG = __add_lvalue_reference_t<__copy_cv_t<_From, _To> >; +}; + +template +struct __copy_cvref<_From&&> { + template + using __apply _LIBCPP_NODEBUG = __add_rvalue_reference_t<__copy_cv_t<_From, _To> >; +}; + +template +using __copy_cvref_t _LIBCPP_NODEBUG = typename __copy_cvref<_From>::template __apply<_To>; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_COPY_CVREF_H diff --git a/src/include/__type_traits/datasizeof.h b/src/include/__type_traits/datasizeof.h new file mode 100644 index 0000000..54735cd --- /dev/null +++ b/src/include/__type_traits/datasizeof.h @@ -0,0 +1,50 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_DATASIZEOF_H +#define _LIBCPP___TYPE_TRAITS_DATASIZEOF_H + +#include <__config> +#include <__cstddef/size_t.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +// This trait provides the size of a type excluding any tail padding. +// +// It is useful in contexts where performing an operation using the full size of the class (including padding) may +// have unintended side effects, such as overwriting a derived class' member when writing the tail padding of a class +// through a pointer-to-base. + +_LIBCPP_BEGIN_NAMESPACE_STD + +// TODO: Enable this again once #94816 is fixed. +#if (__has_keyword(__datasizeof) || __has_extension(datasizeof)) && 0 +template +inline const size_t __datasizeof_v = __datasizeof(_Tp); +#else +template +struct _FirstPaddingByte { + _LIBCPP_NO_UNIQUE_ADDRESS _Tp __v_; + char __first_padding_byte_; +}; + +// _FirstPaddingByte<> is sometimes non-standard layout. +// It is conditionally-supported to use __builtin_offsetof in that case, but GCC and Clang allow it. +_LIBCPP_DIAGNOSTIC_PUSH +_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Winvalid-offsetof") +_LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Winvalid-offsetof") +template +inline const size_t __datasizeof_v = __builtin_offsetof(_FirstPaddingByte<_Tp>, __first_padding_byte_); +_LIBCPP_DIAGNOSTIC_POP +#endif // __has_extension(datasizeof) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_DATASIZEOF_H diff --git a/src/include/__type_traits/decay.h b/src/include/__type_traits/decay.h new file mode 100644 index 0000000..2e3d05d --- /dev/null +++ b/src/include/__type_traits/decay.h @@ -0,0 +1,72 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_DECAY_H +#define _LIBCPP___TYPE_TRAITS_DECAY_H + +#include <__config> +#include <__type_traits/add_pointer.h> +#include <__type_traits/conditional.h> +#include <__type_traits/is_array.h> +#include <__type_traits/is_function.h> +#include <__type_traits/is_referenceable.h> +#include <__type_traits/remove_cv.h> +#include <__type_traits/remove_extent.h> +#include <__type_traits/remove_reference.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if __has_builtin(__decay) +template +using __decay_t _LIBCPP_NODEBUG = __decay(_Tp); + +template +struct _LIBCPP_NO_SPECIALIZATIONS decay { + using type _LIBCPP_NODEBUG = __decay_t<_Tp>; +}; + +#else +template +struct __decay { + using type _LIBCPP_NODEBUG = __remove_cv_t<_Up>; +}; + +template +struct __decay<_Up, true> { +public: + using type _LIBCPP_NODEBUG = + __conditional_t::value, + __add_pointer_t<__remove_extent_t<_Up> >, + __conditional_t::value, typename add_pointer<_Up>::type, __remove_cv_t<_Up> > >; +}; + +template +struct decay { +private: + using _Up _LIBCPP_NODEBUG = __libcpp_remove_reference_t<_Tp>; + +public: + using type _LIBCPP_NODEBUG = typename __decay<_Up, __is_referenceable_v<_Up> >::type; +}; + +template +using __decay_t = typename decay<_Tp>::type; +#endif // __has_builtin(__decay) + +#if _LIBCPP_STD_VER >= 14 +template +using decay_t = __decay_t<_Tp>; +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_DECAY_H diff --git a/src/include/__type_traits/dependent_type.h b/src/include/__type_traits/dependent_type.h new file mode 100644 index 0000000..354705c --- /dev/null +++ b/src/include/__type_traits/dependent_type.h @@ -0,0 +1,25 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_DEPENDENT_TYPE_H +#define _LIBCPP___TYPE_TRAITS_DEPENDENT_TYPE_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +struct __dependent_type : public _Tp {}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_DEPENDENT_TYPE_H diff --git a/src/include/__type_traits/desugars_to.h b/src/include/__type_traits/desugars_to.h new file mode 100644 index 0000000..b67baae --- /dev/null +++ b/src/include/__type_traits/desugars_to.h @@ -0,0 +1,69 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_DESUGARS_TO_H +#define _LIBCPP___TYPE_TRAITS_DESUGARS_TO_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +// Tags to represent the canonical operations. + +// syntactically, the operation is equivalent to calling `a == b` +struct __equal_tag {}; + +// syntactically, the operation is equivalent to calling `a + b` +struct __plus_tag {}; + +// syntactically, the operation is equivalent to calling `a < b` +struct __less_tag {}; + +// syntactically, the operation is equivalent to calling `a > b` +struct __greater_tag {}; + +// syntactically, the operation is equivalent to calling `a < b`, and these expressions +// have to be true for any `a` and `b`: +// - `(a < b) == (b > a)` +// - `(!(a < b) && !(b < a)) == (a == b)` +// For example, this is satisfied for std::less on integral types, but also for ranges::less on all types due to +// additional semantic requirements on that operation. +struct __totally_ordered_less_tag {}; + +// This class template is used to determine whether an operation "desugars" +// (or boils down) to a given canonical operation. +// +// For example, `std::equal_to<>`, our internal `std::__equal_to` helper and +// `ranges::equal_to` are all just fancy ways of representing a transparent +// equality operation, so they all desugar to `__equal_tag`. +// +// This is useful to optimize some functions in cases where we know e.g. the +// predicate being passed is actually going to call a builtin operator, or has +// some specific semantics. +template +inline const bool __desugars_to_v = false; + +// For the purpose of determining whether something desugars to something else, +// we disregard const and ref qualifiers on the operation itself. +template +inline const bool __desugars_to_v<_CanonicalTag, _Operation const, _Args...> = + __desugars_to_v<_CanonicalTag, _Operation, _Args...>; +template +inline const bool __desugars_to_v<_CanonicalTag, _Operation&, _Args...> = + __desugars_to_v<_CanonicalTag, _Operation, _Args...>; +template +inline const bool __desugars_to_v<_CanonicalTag, _Operation&&, _Args...> = + __desugars_to_v<_CanonicalTag, _Operation, _Args...>; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_DESUGARS_TO_H diff --git a/src/include/__type_traits/detected_or.h b/src/include/__type_traits/detected_or.h new file mode 100644 index 0000000..49c0c71 --- /dev/null +++ b/src/include/__type_traits/detected_or.h @@ -0,0 +1,36 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_DETECTED_OR_H +#define _LIBCPP___TYPE_TRAITS_DETECTED_OR_H + +#include <__config> +#include <__type_traits/void_t.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template class _Op, class... _Args> +struct __detector { + using type _LIBCPP_NODEBUG = _Default; +}; + +template class _Op, class... _Args> +struct __detector<_Default, __void_t<_Op<_Args...> >, _Op, _Args...> { + using type _LIBCPP_NODEBUG = _Op<_Args...>; +}; + +template class _Op, class... _Args> +using __detected_or_t _LIBCPP_NODEBUG = typename __detector<_Default, void, _Op, _Args...>::type; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_DETECTED_OR_H diff --git a/src/include/__type_traits/disjunction.h b/src/include/__type_traits/disjunction.h new file mode 100644 index 0000000..8e7a384 --- /dev/null +++ b/src/include/__type_traits/disjunction.h @@ -0,0 +1,58 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_DISJUNCTION_H +#define _LIBCPP___TYPE_TRAITS_DISJUNCTION_H + +#include <__config> +#include <__type_traits/integral_constant.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +struct _OrImpl; + +template <> +struct _OrImpl { + template + using _Result _LIBCPP_NODEBUG = + typename _OrImpl::template _Result<_First, _Rest...>; +}; + +template <> +struct _OrImpl { + template + using _Result _LIBCPP_NODEBUG = _Res; +}; + +// _Or always performs lazy evaluation of its arguments. +// +// However, `_Or<_Pred...>` itself will evaluate its result immediately (without having to +// be instantiated) since it is an alias, unlike `disjunction<_Pred...>`, which is a struct. +// If you want to defer the evaluation of `_Or<_Pred...>` itself, use `_Lazy<_Or, _Pred...>` +// or `disjunction<_Pred...>` directly. +template +using _Or _LIBCPP_NODEBUG = typename _OrImpl::template _Result; + +#if _LIBCPP_STD_VER >= 17 + +template +struct _LIBCPP_NO_SPECIALIZATIONS disjunction : _Or<_Args...> {}; + +template +_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool disjunction_v = _Or<_Args...>::value; + +#endif // _LIBCPP_STD_VER >= 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_DISJUNCTION_H diff --git a/src/include/__type_traits/enable_if.h b/src/include/__type_traits/enable_if.h new file mode 100644 index 0000000..ae1af6e --- /dev/null +++ b/src/include/__type_traits/enable_if.h @@ -0,0 +1,43 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_ENABLE_IF_H +#define _LIBCPP___TYPE_TRAITS_ENABLE_IF_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +struct _LIBCPP_NO_SPECIALIZATIONS enable_if{}; + +_LIBCPP_DIAGNOSTIC_PUSH +#if __has_warning("-Winvalid-specialization") +_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Winvalid-specialization") +#endif +template +struct enable_if { + typedef _Tp type; +}; +_LIBCPP_DIAGNOSTIC_POP + +template +using __enable_if_t _LIBCPP_NODEBUG = typename enable_if<_Bp, _Tp>::type; + +#if _LIBCPP_STD_VER >= 14 +template +using enable_if_t = typename enable_if<_Bp, _Tp>::type; +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_ENABLE_IF_H diff --git a/src/include/__type_traits/extent.h b/src/include/__type_traits/extent.h new file mode 100644 index 0000000..9a82f03 --- /dev/null +++ b/src/include/__type_traits/extent.h @@ -0,0 +1,54 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_EXTENT_H +#define _LIBCPP___TYPE_TRAITS_EXTENT_H + +#include <__config> +#include <__cstddef/size_t.h> +#include <__type_traits/integral_constant.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if __has_builtin(__array_extent) + +template +struct _LIBCPP_NO_SPECIALIZATIONS extent : integral_constant {}; + +# if _LIBCPP_STD_VER >= 17 +template +_LIBCPP_NO_SPECIALIZATIONS inline constexpr size_t extent_v = __array_extent(_Tp, _Ip); +# endif + +#else // __has_builtin(__array_extent) + +template +struct extent : public integral_constant {}; +template +struct extent<_Tp[], 0> : public integral_constant {}; +template +struct extent<_Tp[], _Ip> : public integral_constant::value> {}; +template +struct extent<_Tp[_Np], 0> : public integral_constant {}; +template +struct extent<_Tp[_Np], _Ip> : public integral_constant::value> {}; + +# if _LIBCPP_STD_VER >= 17 +template +inline constexpr size_t extent_v = extent<_Tp, _Ip>::value; +# endif + +#endif // __has_builtin(__array_extent) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_EXTENT_H diff --git a/src/include/__type_traits/has_unique_object_representation.h b/src/include/__type_traits/has_unique_object_representation.h new file mode 100644 index 0000000..ba81be6 --- /dev/null +++ b/src/include/__type_traits/has_unique_object_representation.h @@ -0,0 +1,41 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_HAS_UNIQUE_OBJECT_REPRESENTATION_H +#define _LIBCPP___TYPE_TRAITS_HAS_UNIQUE_OBJECT_REPRESENTATION_H + +#include <__config> +#include <__type_traits/integral_constant.h> +#include <__type_traits/remove_all_extents.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER >= 17 + +template +struct _LIBCPP_NO_SPECIALIZATIONS has_unique_object_representations + // TODO: We work around a Clang and GCC bug in __has_unique_object_representations by using remove_all_extents + // even though it should not be necessary. This was reported to the compilers: + // - Clang: https://github.com/llvm/llvm-project/issues/95311 + // - GCC: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115476 + // remove_all_extents_t can be removed once all the compilers we support have fixed this bug. + : public integral_constant)> {}; + +template +_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool has_unique_object_representations_v = + __has_unique_object_representations(_Tp); + +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_HAS_UNIQUE_OBJECT_REPRESENTATION_H diff --git a/src/include/__type_traits/has_virtual_destructor.h b/src/include/__type_traits/has_virtual_destructor.h new file mode 100644 index 0000000..bceb61a --- /dev/null +++ b/src/include/__type_traits/has_virtual_destructor.h @@ -0,0 +1,32 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_HAS_VIRTUAL_DESTRUCTOR_H +#define _LIBCPP___TYPE_TRAITS_HAS_VIRTUAL_DESTRUCTOR_H + +#include <__config> +#include <__type_traits/integral_constant.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +struct _LIBCPP_NO_SPECIALIZATIONS has_virtual_destructor + : public integral_constant {}; + +#if _LIBCPP_STD_VER >= 17 +template +_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool has_virtual_destructor_v = __has_virtual_destructor(_Tp); +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_HAS_VIRTUAL_DESTRUCTOR_H diff --git a/src/include/__type_traits/integral_constant.h b/src/include/__type_traits/integral_constant.h new file mode 100644 index 0000000..ff55a85 --- /dev/null +++ b/src/include/__type_traits/integral_constant.h @@ -0,0 +1,44 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_INTEGRAL_CONSTANT_H +#define _LIBCPP___TYPE_TRAITS_INTEGRAL_CONSTANT_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +struct _LIBCPP_NO_SPECIALIZATIONS integral_constant { + static inline _LIBCPP_CONSTEXPR const _Tp value = __v; + typedef _Tp value_type; + typedef integral_constant type; + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR operator value_type() const _NOEXCEPT { return value; } +#if _LIBCPP_STD_VER >= 14 + _LIBCPP_HIDE_FROM_ABI constexpr value_type operator()() const _NOEXCEPT { return value; } +#endif +}; + +typedef integral_constant true_type; +typedef integral_constant false_type; + +template +using _BoolConstant _LIBCPP_NODEBUG = integral_constant; + +#if _LIBCPP_STD_VER >= 17 +template +using bool_constant = integral_constant; +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_INTEGRAL_CONSTANT_H diff --git a/src/include/__type_traits/invoke.h b/src/include/__type_traits/invoke.h new file mode 100644 index 0000000..ccf8620 --- /dev/null +++ b/src/include/__type_traits/invoke.h @@ -0,0 +1,318 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_INVOKE_H +#define _LIBCPP___TYPE_TRAITS_INVOKE_H + +#include <__config> +#include <__type_traits/conditional.h> +#include <__type_traits/decay.h> +#include <__type_traits/enable_if.h> +#include <__type_traits/integral_constant.h> +#include <__type_traits/is_base_of.h> +#include <__type_traits/is_core_convertible.h> +#include <__type_traits/is_member_pointer.h> +#include <__type_traits/is_reference_wrapper.h> +#include <__type_traits/is_same.h> +#include <__type_traits/is_void.h> +#include <__type_traits/nat.h> +#include <__utility/declval.h> +#include <__utility/forward.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +// This file defines the following libc++-internal API (back-ported to C++03): +// +// template +// decltype(auto) __invoke(Args&&... args) noexcept(noexcept(std::invoke(std::forward(args...)))) { +// return std::invoke(std::forward(args)...); +// } +// +// template +// Ret __invoke_r(Args&&... args) { +// return std::invoke_r(std::forward(args)...); +// } +// +// template +// inline const bool __is_invocable_r_v = is_invocable_r_v; +// +// template +// struct __is_invocable : is_invocable {}; +// +// template +// inline const bool __is_invocable_v = is_invocable_v; +// +// template +// inline const bool __is_nothrow_invocable_v = is_nothrow_invocable_v; +// +// template +// struct __invoke_result : invoke_result {}; +// +// template +// using __invoke_result_t = invoke_result_t; + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +struct __member_pointer_class_type {}; + +template +struct __member_pointer_class_type<_Ret _ClassType::*> { + typedef _ClassType type; +}; + +template , + class _DecayA0 = __decay_t<_A0>, + class _ClassT = typename __member_pointer_class_type<_DecayFp>::type> +using __enable_if_bullet1 _LIBCPP_NODEBUG = + __enable_if_t::value && + (is_same<_ClassT, _DecayA0>::value || is_base_of<_ClassT, _DecayA0>::value)>; + +template , class _DecayA0 = __decay_t<_A0> > +using __enable_if_bullet2 _LIBCPP_NODEBUG = + __enable_if_t::value && __is_reference_wrapper<_DecayA0>::value>; + +template , + class _DecayA0 = __decay_t<_A0>, + class _ClassT = typename __member_pointer_class_type<_DecayFp>::type> +using __enable_if_bullet3 _LIBCPP_NODEBUG = + __enable_if_t::value && + !(is_same<_ClassT, _DecayA0>::value || is_base_of<_ClassT, _DecayA0>::value) && + !__is_reference_wrapper<_DecayA0>::value>; + +template , + class _DecayA0 = __decay_t<_A0>, + class _ClassT = typename __member_pointer_class_type<_DecayFp>::type> +using __enable_if_bullet4 _LIBCPP_NODEBUG = + __enable_if_t::value && + (is_same<_ClassT, _DecayA0>::value || is_base_of<_ClassT, _DecayA0>::value)>; + +template , class _DecayA0 = __decay_t<_A0> > +using __enable_if_bullet5 _LIBCPP_NODEBUG = + __enable_if_t::value && __is_reference_wrapper<_DecayA0>::value>; + +template , + class _DecayA0 = __decay_t<_A0>, + class _ClassT = typename __member_pointer_class_type<_DecayFp>::type> +using __enable_if_bullet6 _LIBCPP_NODEBUG = + __enable_if_t::value && + !(is_same<_ClassT, _DecayA0>::value || is_base_of<_ClassT, _DecayA0>::value) && + !__is_reference_wrapper<_DecayA0>::value>; + +// __invoke forward declarations + +// fall back - none of the bullets + +template +__nat __invoke(_Args&&... __args); + +// bullets 1, 2 and 3 + +// clang-format off +template > +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR +decltype((std::declval<_A0>().*std::declval<_Fp>())(std::declval<_Args>()...)) +__invoke(_Fp&& __f, _A0&& __a0, _Args&&... __args) + _NOEXCEPT_(noexcept((static_cast<_A0&&>(__a0).*__f)(static_cast<_Args&&>(__args)...))) + { return (static_cast<_A0&&>(__a0).*__f)(static_cast<_Args&&>(__args)...); } + +template > +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR +decltype((std::declval<_A0>().get().*std::declval<_Fp>())(std::declval<_Args>()...)) +__invoke(_Fp&& __f, _A0&& __a0, _Args&&... __args) + _NOEXCEPT_(noexcept((__a0.get().*__f)(static_cast<_Args&&>(__args)...))) + { return (__a0.get().*__f)(static_cast<_Args&&>(__args)...); } + +template > +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR +decltype(((*std::declval<_A0>()).*std::declval<_Fp>())(std::declval<_Args>()...)) +__invoke(_Fp&& __f, _A0&& __a0, _Args&&... __args) + _NOEXCEPT_(noexcept(((*static_cast<_A0&&>(__a0)).*__f)(static_cast<_Args&&>(__args)...))) + { return ((*static_cast<_A0&&>(__a0)).*__f)(static_cast<_Args&&>(__args)...); } + +// bullets 4, 5 and 6 + +template > +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR +decltype(std::declval<_A0>().*std::declval<_Fp>()) +__invoke(_Fp&& __f, _A0&& __a0) + _NOEXCEPT_(noexcept(static_cast<_A0&&>(__a0).*__f)) + { return static_cast<_A0&&>(__a0).*__f; } + +template > +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR +decltype(std::declval<_A0>().get().*std::declval<_Fp>()) +__invoke(_Fp&& __f, _A0&& __a0) + _NOEXCEPT_(noexcept(__a0.get().*__f)) + { return __a0.get().*__f; } + +template > +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR +decltype((*std::declval<_A0>()).*std::declval<_Fp>()) +__invoke(_Fp&& __f, _A0&& __a0) + _NOEXCEPT_(noexcept((*static_cast<_A0&&>(__a0)).*__f)) + { return (*static_cast<_A0&&>(__a0)).*__f; } + +// bullet 7 + +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR +decltype(std::declval<_Fp>()(std::declval<_Args>()...)) +__invoke(_Fp&& __f, _Args&&... __args) + _NOEXCEPT_(noexcept(static_cast<_Fp&&>(__f)(static_cast<_Args&&>(__args)...))) + { return static_cast<_Fp&&>(__f)(static_cast<_Args&&>(__args)...); } +// clang-format on + +// __invokable +template +struct __invokable_r { + template + static decltype(std::__invoke(std::declval<_XFp>(), std::declval<_XArgs>()...)) __try_call(int); + template + static __nat __try_call(...); + + // FIXME: Check that _Ret, _Fp, and _Args... are all complete types, cv void, + // or incomplete array types as required by the standard. + using _Result _LIBCPP_NODEBUG = decltype(__try_call<_Fp, _Args...>(0)); + + using type = __conditional_t<_IsNotSame<_Result, __nat>::value, + __conditional_t::value, true_type, __is_core_convertible<_Result, _Ret> >, + false_type>; + static const bool value = type::value; +}; +template +using __is_invocable _LIBCPP_NODEBUG = __invokable_r; + +template +struct __nothrow_invokable_r_imp { + static const bool value = false; +}; + +template +struct __nothrow_invokable_r_imp { + typedef __nothrow_invokable_r_imp _ThisT; + + template + static void __test_noexcept(_Tp) _NOEXCEPT; + +#ifdef _LIBCPP_CXX03_LANG + static const bool value = false; +#else + static const bool value = + noexcept(_ThisT::__test_noexcept<_Ret>(std::__invoke(std::declval<_Fp>(), std::declval<_Args>()...))); +#endif +}; + +template +struct __nothrow_invokable_r_imp { +#ifdef _LIBCPP_CXX03_LANG + static const bool value = false; +#else + static const bool value = noexcept(std::__invoke(std::declval<_Fp>(), std::declval<_Args>()...)); +#endif +}; + +template +using __nothrow_invokable_r _LIBCPP_NODEBUG = + __nothrow_invokable_r_imp<__invokable_r<_Ret, _Fp, _Args...>::value, is_void<_Ret>::value, _Ret, _Fp, _Args...>; + +template +using __nothrow_invokable _LIBCPP_NODEBUG = + __nothrow_invokable_r_imp<__is_invocable<_Fp, _Args...>::value, true, void, _Fp, _Args...>; + +template ::value> +struct __invoke_void_return_wrapper { + template + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static _Ret __call(_Args&&... __args) { + return std::__invoke(std::forward<_Args>(__args)...); + } +}; + +template +struct __invoke_void_return_wrapper<_Ret, true> { + template + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static void __call(_Args&&... __args) { + std::__invoke(std::forward<_Args>(__args)...); + } +}; + +template +inline const bool __is_invocable_v = __is_invocable<_Func, _Args...>::value; + +template +inline const bool __is_invocable_r_v = __invokable_r<_Ret, _Func, _Args...>::value; + +template +inline const bool __is_nothrow_invocable_v = __nothrow_invokable<_Func, _Args...>::value; + +template +struct __invoke_result + : enable_if<__is_invocable_v<_Func, _Args...>, typename __invokable_r::_Result> {}; + +template +using __invoke_result_t _LIBCPP_NODEBUG = typename __invoke_result<_Func, _Args...>::type; + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Ret __invoke_r(_Args&&... __args) { + return __invoke_void_return_wrapper<_Ret>::__call(std::forward<_Args>(__args)...); +} + +#if _LIBCPP_STD_VER >= 17 + +// is_invocable + +template +struct _LIBCPP_NO_SPECIALIZATIONS is_invocable : bool_constant<__is_invocable_v<_Fn, _Args...>> {}; + +template +struct _LIBCPP_NO_SPECIALIZATIONS is_invocable_r : bool_constant<__is_invocable_r_v<_Ret, _Fn, _Args...>> {}; + +template +_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_invocable_v = __is_invocable_v<_Fn, _Args...>; + +template +_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_invocable_r_v = __is_invocable_r_v<_Ret, _Fn, _Args...>; + +// is_nothrow_invocable + +template +struct _LIBCPP_NO_SPECIALIZATIONS is_nothrow_invocable : bool_constant<__nothrow_invokable<_Fn, _Args...>::value> {}; + +template +struct _LIBCPP_NO_SPECIALIZATIONS is_nothrow_invocable_r + : bool_constant<__nothrow_invokable_r<_Ret, _Fn, _Args...>::value> {}; + +template +_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_nothrow_invocable_v = is_nothrow_invocable<_Fn, _Args...>::value; + +template +_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_nothrow_invocable_r_v = + is_nothrow_invocable_r<_Ret, _Fn, _Args...>::value; + +template +struct _LIBCPP_NO_SPECIALIZATIONS invoke_result : __invoke_result<_Fn, _Args...> {}; + +template +using invoke_result_t = typename invoke_result<_Fn, _Args...>::type; + +#endif // _LIBCPP_STD_VER >= 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_INVOKE_H diff --git a/src/include/__type_traits/is_abstract.h b/src/include/__type_traits/is_abstract.h new file mode 100644 index 0000000..e2f68f2 --- /dev/null +++ b/src/include/__type_traits/is_abstract.h @@ -0,0 +1,31 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_IS_ABSTRACT_H +#define _LIBCPP___TYPE_TRAITS_IS_ABSTRACT_H + +#include <__config> +#include <__type_traits/integral_constant.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +struct _LIBCPP_NO_SPECIALIZATIONS is_abstract : integral_constant {}; + +#if _LIBCPP_STD_VER >= 17 +template +_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_abstract_v = __is_abstract(_Tp); +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_IS_ABSTRACT_H diff --git a/src/include/__type_traits/is_aggregate.h b/src/include/__type_traits/is_aggregate.h new file mode 100644 index 0000000..d1acec6 --- /dev/null +++ b/src/include/__type_traits/is_aggregate.h @@ -0,0 +1,33 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_IS_AGGREGATE_H +#define _LIBCPP___TYPE_TRAITS_IS_AGGREGATE_H + +#include <__config> +#include <__type_traits/integral_constant.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER >= 17 + +template +struct _LIBCPP_NO_SPECIALIZATIONS is_aggregate : integral_constant {}; + +template +_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_aggregate_v = __is_aggregate(_Tp); + +#endif // _LIBCPP_STD_VER >= 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_IS_AGGREGATE_H diff --git a/src/include/__type_traits/is_allocator.h b/src/include/__type_traits/is_allocator.h new file mode 100644 index 0000000..191eeb9 --- /dev/null +++ b/src/include/__type_traits/is_allocator.h @@ -0,0 +1,34 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_IS_ALLOCATOR_H +#define _LIBCPP___TYPE_IS_ALLOCATOR_H + +#include <__config> +#include <__cstddef/size_t.h> +#include <__type_traits/integral_constant.h> +#include <__type_traits/void_t.h> +#include <__utility/declval.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +struct __is_allocator : false_type {}; + +template +struct __is_allocator<_Alloc, + __void_t, + __void_t().allocate(size_t(0)))> > : true_type {}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_IS_ALLOCATOR_H diff --git a/src/include/__type_traits/is_always_bitcastable.h b/src/include/__type_traits/is_always_bitcastable.h new file mode 100644 index 0000000..044d250 --- /dev/null +++ b/src/include/__type_traits/is_always_bitcastable.h @@ -0,0 +1,83 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_IS_ALWAYS_BITCASTABLE_H +#define _LIBCPP___TYPE_TRAITS_IS_ALWAYS_BITCASTABLE_H + +#include <__config> +#include <__type_traits/is_integral.h> +#include <__type_traits/is_same.h> +#include <__type_traits/is_trivially_copyable.h> +#include <__type_traits/remove_cv.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +// Checks whether an object of type `From` can always be bit-cast to an object of type `To` and represent a valid value +// of type `To`. In other words, `From` and `To` have the same value representation and the set of values of `From` is +// a subset of the set of values of `To`. +// +// Note that types that cannot be assigned to each other using built-in assignment (e.g. arrays) might still be +// considered bit-castable. +template +struct __is_always_bitcastable { + using _UnqualFrom _LIBCPP_NODEBUG = __remove_cv_t<_From>; + using _UnqualTo _LIBCPP_NODEBUG = __remove_cv_t<_To>; + + // clang-format off + static const bool value = + // First, the simple case -- `From` and `To` are the same object type. + (is_same<_UnqualFrom, _UnqualTo>::value && is_trivially_copyable<_UnqualFrom>::value) || + + // Beyond the simple case, we say that one type is "always bit-castable" to another if: + // - (1) `From` and `To` have the same value representation, and in addition every possible value of `From` has + // a corresponding value in the `To` type (in other words, the set of values of `To` is a superset of the set of + // values of `From`); + // - (2) When the corresponding values are not the same value (as, for example, between an unsigned and a signed + // integer, where a large positive value of the unsigned integer corresponds to a negative value in the signed + // integer type), the value of `To` that results from a bitwise copy of `From` is the same what would be + // produced by the built-in assignment (if it were defined for the two types, to which there are minor + // exceptions, e.g. built-in arrays). + // + // In practice, that means: + // - all integral types (except `bool`, see below) -- that is, character types and `int` types, both signed and + // unsigned... + // - as well as arrays of such types... + // - ...that have the same size. + // + // Other trivially-copyable types can't be validly bit-cast outside of their own type: + // - floating-point types normally have different sizes and thus aren't bit-castable between each other (fails + // #1); + // - integral types and floating-point types use different representations, so for example bit-casting an integral + // `1` to `float` results in a very small less-than-one value, unlike built-in assignment that produces `1.0` + // (fails #2); + // - booleans normally use only a single bit of their object representation; bit-casting an integer to a boolean + // will result in a boolean object with an incorrect representation, which is undefined behavior (fails #2). + // Bit-casting from a boolean into an integer, however, is valid; + // - enumeration types may have different ranges of possible values (fails #1); + // - for pointers, it is not guaranteed that pointers to different types use the same set of values to represent + // addresses, and the conversion results are explicitly unspecified for types with different alignments + // (fails #1); + // - for structs and unions it is impossible to determine whether the set of values of one of them is a subset of + // the other (fails #1); + // - there is no need to consider `nullptr_t` for practical purposes. + ( + sizeof(_From) == sizeof(_To) && + is_integral<_From>::value && + is_integral<_To>::value && + !is_same<_UnqualTo, bool>::value + ); + // clang-format on +}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_IS_ALWAYS_BITCASTABLE_H diff --git a/src/include/__type_traits/is_arithmetic.h b/src/include/__type_traits/is_arithmetic.h new file mode 100644 index 0000000..0d5c293 --- /dev/null +++ b/src/include/__type_traits/is_arithmetic.h @@ -0,0 +1,34 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_IS_ARITHMETIC_H +#define _LIBCPP___TYPE_TRAITS_IS_ARITHMETIC_H + +#include <__config> +#include <__type_traits/integral_constant.h> +#include <__type_traits/is_floating_point.h> +#include <__type_traits/is_integral.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +struct _LIBCPP_NO_SPECIALIZATIONS is_arithmetic + : integral_constant::value || is_floating_point<_Tp>::value> {}; + +#if _LIBCPP_STD_VER >= 17 +template +_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_arithmetic_v = is_arithmetic<_Tp>::value; +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_IS_ARITHMETIC_H diff --git a/src/include/__type_traits/is_array.h b/src/include/__type_traits/is_array.h new file mode 100644 index 0000000..1d94370 --- /dev/null +++ b/src/include/__type_traits/is_array.h @@ -0,0 +1,51 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_IS_ARRAY_H +#define _LIBCPP___TYPE_TRAITS_IS_ARRAY_H + +#include <__config> +#include <__cstddef/size_t.h> +#include <__type_traits/integral_constant.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if __has_builtin(__is_array) && \ + (!defined(_LIBCPP_COMPILER_CLANG_BASED) || (defined(_LIBCPP_CLANG_VER) && _LIBCPP_CLANG_VER >= 1900)) + +template +struct _LIBCPP_NO_SPECIALIZATIONS is_array : _BoolConstant<__is_array(_Tp)> {}; + +# if _LIBCPP_STD_VER >= 17 +template +_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_array_v = __is_array(_Tp); +# endif + +#else + +template +struct is_array : public false_type {}; +template +struct is_array<_Tp[]> : public true_type {}; +template +struct is_array<_Tp[_Np]> : public true_type {}; + +# if _LIBCPP_STD_VER >= 17 +template +inline constexpr bool is_array_v = is_array<_Tp>::value; +# endif + +#endif // __has_builtin(__is_array) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_IS_ARRAY_H diff --git a/src/include/__type_traits/is_assignable.h b/src/include/__type_traits/is_assignable.h new file mode 100644 index 0000000..253e86b --- /dev/null +++ b/src/include/__type_traits/is_assignable.h @@ -0,0 +1,51 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_IS_ASSIGNABLE_H +#define _LIBCPP___TYPE_TRAITS_IS_ASSIGNABLE_H + +#include <__config> +#include <__type_traits/add_lvalue_reference.h> +#include <__type_traits/add_rvalue_reference.h> +#include <__type_traits/integral_constant.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +struct _LIBCPP_NO_SPECIALIZATIONS is_assignable : _BoolConstant<__is_assignable(_Tp, _Up)> {}; + +#if _LIBCPP_STD_VER >= 17 +template +_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_assignable_v = __is_assignable(_Tp, _Arg); +#endif + +template +struct _LIBCPP_NO_SPECIALIZATIONS is_copy_assignable + : integral_constant, __add_lvalue_reference_t)> {}; + +#if _LIBCPP_STD_VER >= 17 +template +_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_copy_assignable_v = is_copy_assignable<_Tp>::value; +#endif + +template +struct _LIBCPP_NO_SPECIALIZATIONS is_move_assignable + : integral_constant, __add_rvalue_reference_t<_Tp>)> {}; + +#if _LIBCPP_STD_VER >= 17 +template +_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_move_assignable_v = is_move_assignable<_Tp>::value; +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_IS_ASSIGNABLE_H diff --git a/src/include/__type_traits/is_base_of.h b/src/include/__type_traits/is_base_of.h new file mode 100644 index 0000000..afbe8ca --- /dev/null +++ b/src/include/__type_traits/is_base_of.h @@ -0,0 +1,43 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_IS_BASE_OF_H +#define _LIBCPP___TYPE_TRAITS_IS_BASE_OF_H + +#include <__config> +#include <__type_traits/integral_constant.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +struct _LIBCPP_NO_SPECIALIZATIONS is_base_of : integral_constant {}; + +#if _LIBCPP_STD_VER >= 17 +template +_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_base_of_v = __is_base_of(_Bp, _Dp); +#endif + +#if _LIBCPP_STD_VER >= 26 +# if __has_builtin(__builtin_is_virtual_base_of) + +template +struct _LIBCPP_NO_SPECIALIZATIONS is_virtual_base_of : bool_constant<__builtin_is_virtual_base_of(_Base, _Derived)> {}; + +template +_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_virtual_base_of_v = __builtin_is_virtual_base_of(_Base, _Derived); + +# endif +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_IS_BASE_OF_H diff --git a/src/include/__type_traits/is_bounded_array.h b/src/include/__type_traits/is_bounded_array.h new file mode 100644 index 0000000..aec4888 --- /dev/null +++ b/src/include/__type_traits/is_bounded_array.h @@ -0,0 +1,47 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_IS_BOUNDED_ARRAY_H +#define _LIBCPP___TYPE_TRAITS_IS_BOUNDED_ARRAY_H + +#include <__config> +#include <__cstddef/size_t.h> +#include <__type_traits/integral_constant.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +inline const bool __is_bounded_array_v = false; +template +inline const bool __is_bounded_array_v<_Tp[_Np]> = true; + +#if _LIBCPP_STD_VER >= 20 + +template +struct _LIBCPP_NO_SPECIALIZATIONS is_bounded_array : false_type {}; + +_LIBCPP_DIAGNOSTIC_PUSH +# if __has_warning("-Winvalid-specialization") +_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Winvalid-specialization") +# endif +template +struct is_bounded_array<_Tp[_Np]> : true_type {}; +_LIBCPP_DIAGNOSTIC_POP + +template +_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_bounded_array_v = is_bounded_array<_Tp>::value; + +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_IS_BOUNDED_ARRAY_H diff --git a/src/include/__type_traits/is_callable.h b/src/include/__type_traits/is_callable.h new file mode 100644 index 0000000..49724fe --- /dev/null +++ b/src/include/__type_traits/is_callable.h @@ -0,0 +1,32 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_IS_CALLABLE_H +#define _LIBCPP___TYPE_TRAITS_IS_CALLABLE_H + +#include <__config> +#include <__type_traits/integral_constant.h> +#include <__utility/declval.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template ()(std::declval<_Args>()...))> +true_type __is_callable_helper(int); +template +false_type __is_callable_helper(...); + +template +struct __is_callable : decltype(std::__is_callable_helper<_Func, _Args...>(0)) {}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_IS_CALLABLE_H diff --git a/src/include/__type_traits/is_char_like_type.h b/src/include/__type_traits/is_char_like_type.h new file mode 100644 index 0000000..ca440b5 --- /dev/null +++ b/src/include/__type_traits/is_char_like_type.h @@ -0,0 +1,30 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_IS_CHAR_LIKE_TYPE_H +#define _LIBCPP___TYPE_TRAITS_IS_CHAR_LIKE_TYPE_H + +#include <__config> +#include <__type_traits/conjunction.h> +#include <__type_traits/is_standard_layout.h> +#include <__type_traits/is_trivially_constructible.h> +#include <__type_traits/is_trivially_copyable.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +using _IsCharLikeType _LIBCPP_NODEBUG = + _And, is_trivially_default_constructible<_CharT>, is_trivially_copyable<_CharT> >; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_IS_CHAR_LIKE_TYPE_H diff --git a/src/include/__type_traits/is_class.h b/src/include/__type_traits/is_class.h new file mode 100644 index 0000000..ba466f1 --- /dev/null +++ b/src/include/__type_traits/is_class.h @@ -0,0 +1,31 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_IS_CLASS_H +#define _LIBCPP___TYPE_TRAITS_IS_CLASS_H + +#include <__config> +#include <__type_traits/integral_constant.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +struct _LIBCPP_NO_SPECIALIZATIONS is_class : integral_constant {}; + +#if _LIBCPP_STD_VER >= 17 +template +_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_class_v = __is_class(_Tp); +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_IS_CLASS_H diff --git a/src/include/__type_traits/is_compound.h b/src/include/__type_traits/is_compound.h new file mode 100644 index 0000000..1ecedb6 --- /dev/null +++ b/src/include/__type_traits/is_compound.h @@ -0,0 +1,46 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_IS_COMPOUND_H +#define _LIBCPP___TYPE_TRAITS_IS_COMPOUND_H + +#include <__config> +#include <__type_traits/integral_constant.h> +#include <__type_traits/is_fundamental.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if __has_builtin(__is_compound) + +template +struct _LIBCPP_NO_SPECIALIZATIONS is_compound : _BoolConstant<__is_compound(_Tp)> {}; + +# if _LIBCPP_STD_VER >= 17 +template +_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_compound_v = __is_compound(_Tp); +# endif + +#else // __has_builtin(__is_compound) + +template +struct is_compound : public integral_constant::value> {}; + +# if _LIBCPP_STD_VER >= 17 +template +inline constexpr bool is_compound_v = is_compound<_Tp>::value; +# endif + +#endif // __has_builtin(__is_compound) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_IS_COMPOUND_H diff --git a/src/include/__type_traits/is_const.h b/src/include/__type_traits/is_const.h new file mode 100644 index 0000000..4ec354d --- /dev/null +++ b/src/include/__type_traits/is_const.h @@ -0,0 +1,47 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_IS_CONST_H +#define _LIBCPP___TYPE_TRAITS_IS_CONST_H + +#include <__config> +#include <__type_traits/integral_constant.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if __has_builtin(__is_const) + +template +struct _LIBCPP_NO_SPECIALIZATIONS is_const : _BoolConstant<__is_const(_Tp)> {}; + +# if _LIBCPP_STD_VER >= 17 +template +_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_const_v = __is_const(_Tp); +# endif + +#else + +template +struct is_const : public false_type {}; +template +struct is_const<_Tp const> : public true_type {}; + +# if _LIBCPP_STD_VER >= 17 +template +inline constexpr bool is_const_v = is_const<_Tp>::value; +# endif + +#endif // __has_builtin(__is_const) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_IS_CONST_H diff --git a/src/include/__type_traits/is_constant_evaluated.h b/src/include/__type_traits/is_constant_evaluated.h new file mode 100644 index 0000000..05e070a --- /dev/null +++ b/src/include/__type_traits/is_constant_evaluated.h @@ -0,0 +1,32 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_IS_CONSTANT_EVALUATED_H +#define _LIBCPP___TYPE_TRAITS_IS_CONSTANT_EVALUATED_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER >= 20 +_LIBCPP_HIDE_FROM_ABI inline constexpr bool is_constant_evaluated() noexcept { + return __builtin_is_constant_evaluated(); +} +#endif + +_LIBCPP_HIDE_FROM_ABI inline _LIBCPP_CONSTEXPR bool __libcpp_is_constant_evaluated() _NOEXCEPT { + return __builtin_is_constant_evaluated(); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_IS_CONSTANT_EVALUATED_H diff --git a/src/include/__type_traits/is_constructible.h b/src/include/__type_traits/is_constructible.h new file mode 100644 index 0000000..feafb70 --- /dev/null +++ b/src/include/__type_traits/is_constructible.h @@ -0,0 +1,59 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_IS_CONSTRUCTIBLE_H +#define _LIBCPP___TYPE_IS_CONSTRUCTIBLE_H + +#include <__config> +#include <__type_traits/add_lvalue_reference.h> +#include <__type_traits/add_rvalue_reference.h> +#include <__type_traits/integral_constant.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +struct _LIBCPP_NO_SPECIALIZATIONS is_constructible : integral_constant {}; + +#if _LIBCPP_STD_VER >= 17 +template +_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_constructible_v = __is_constructible(_Tp, _Args...); +#endif + +template +struct _LIBCPP_NO_SPECIALIZATIONS is_copy_constructible + : integral_constant)> {}; + +#if _LIBCPP_STD_VER >= 17 +template +_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_copy_constructible_v = is_copy_constructible<_Tp>::value; +#endif + +template +struct _LIBCPP_NO_SPECIALIZATIONS is_move_constructible + : integral_constant)> {}; + +#if _LIBCPP_STD_VER >= 17 +template +_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_move_constructible_v = is_move_constructible<_Tp>::value; +#endif + +template +struct _LIBCPP_NO_SPECIALIZATIONS is_default_constructible : integral_constant {}; + +#if _LIBCPP_STD_VER >= 17 +template +_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_default_constructible_v = __is_constructible(_Tp); +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_IS_CONSTRUCTIBLE_H diff --git a/src/include/__type_traits/is_convertible.h b/src/include/__type_traits/is_convertible.h new file mode 100644 index 0000000..f0a859f --- /dev/null +++ b/src/include/__type_traits/is_convertible.h @@ -0,0 +1,41 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_IS_CONVERTIBLE_H +#define _LIBCPP___TYPE_TRAITS_IS_CONVERTIBLE_H + +#include <__config> +#include <__type_traits/integral_constant.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +struct _LIBCPP_NO_SPECIALIZATIONS is_convertible : integral_constant {}; + +#if _LIBCPP_STD_VER >= 17 +template +_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_convertible_v = __is_convertible(_From, _To); +#endif + +#if _LIBCPP_STD_VER >= 20 + +template +struct _LIBCPP_NO_SPECIALIZATIONS is_nothrow_convertible : bool_constant<__is_nothrow_convertible(_Tp, _Up)> {}; + +template +_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_nothrow_convertible_v = __is_nothrow_convertible(_Tp, _Up); + +#endif // _LIBCPP_STD_VER >= 20 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_IS_CONVERTIBLE_H diff --git a/src/include/__type_traits/is_core_convertible.h b/src/include/__type_traits/is_core_convertible.h new file mode 100644 index 0000000..ca3a346 --- /dev/null +++ b/src/include/__type_traits/is_core_convertible.h @@ -0,0 +1,42 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_IS_CORE_CONVERTIBLE_H +#define _LIBCPP___TYPE_TRAITS_IS_CORE_CONVERTIBLE_H + +#include <__config> +#include <__type_traits/integral_constant.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +// [conv.general]/3 says "E is convertible to T" whenever "T t=E;" is well-formed. +// We can't test for that, but we can test implicit convertibility by passing it +// to a function. Notice that __is_core_convertible is false, +// and __is_core_convertible is true in C++17 and later. + +template +struct __is_core_convertible : false_type {}; + +template +struct __is_core_convertible<_Tp, _Up, decltype(static_cast(0)(static_cast<_Tp (*)()>(0)()))> + : true_type {}; + +#if _LIBCPP_STD_VER >= 20 + +template +concept __core_convertible_to = __is_core_convertible<_Tp, _Up>::value; + +#endif // _LIBCPP_STD_VER >= 20 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_IS_CORE_CONVERTIBLE_H diff --git a/src/include/__type_traits/is_destructible.h b/src/include/__type_traits/is_destructible.h new file mode 100644 index 0000000..ae661a4 --- /dev/null +++ b/src/include/__type_traits/is_destructible.h @@ -0,0 +1,97 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_IS_DESTRUCTIBLE_H +#define _LIBCPP___TYPE_TRAITS_IS_DESTRUCTIBLE_H + +#include <__config> +#include <__type_traits/integral_constant.h> +#include <__type_traits/is_function.h> +#include <__type_traits/is_reference.h> +#include <__type_traits/remove_all_extents.h> +#include <__utility/declval.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if __has_builtin(__is_destructible) + +template +struct _LIBCPP_NO_SPECIALIZATIONS is_destructible : _BoolConstant<__is_destructible(_Tp)> {}; + +# if _LIBCPP_STD_VER >= 17 +template +_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_destructible_v = __is_destructible(_Tp); +# endif + +#else // __has_builtin(__is_destructible) + +// if it's a reference, return true +// if it's a function, return false +// if it's void, return false +// if it's an array of unknown bound, return false +// Otherwise, return "declval<_Up&>().~_Up()" is well-formed +// where _Up is remove_all_extents<_Tp>::type + +template +struct __is_destructible_apply { + typedef int type; +}; + +template +struct __is_destructor_wellformed { + template + static true_type __test(typename __is_destructible_apply().~_Tp1())>::type); + + template + static false_type __test(...); + + static const bool value = decltype(__test<_Tp>(12))::value; +}; + +template +struct __destructible_imp; + +template +struct __destructible_imp<_Tp, false> + : integral_constant >::value> {}; + +template +struct __destructible_imp<_Tp, true> : true_type {}; + +template +struct __destructible_false; + +template +struct __destructible_false<_Tp, false> : __destructible_imp<_Tp, is_reference<_Tp>::value> {}; + +template +struct __destructible_false<_Tp, true> : false_type {}; + +template +struct is_destructible : __destructible_false<_Tp, is_function<_Tp>::value> {}; + +template +struct is_destructible<_Tp[]> : false_type {}; + +template <> +struct is_destructible : false_type {}; + +# if _LIBCPP_STD_VER >= 17 +template +inline constexpr bool is_destructible_v = is_destructible<_Tp>::value; +# endif + +#endif // __has_builtin(__is_destructible) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_IS_DESTRUCTIBLE_H diff --git a/src/include/__type_traits/is_empty.h b/src/include/__type_traits/is_empty.h new file mode 100644 index 0000000..be6a0d1 --- /dev/null +++ b/src/include/__type_traits/is_empty.h @@ -0,0 +1,31 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_IS_EMPTY_H +#define _LIBCPP___TYPE_TRAITS_IS_EMPTY_H + +#include <__config> +#include <__type_traits/integral_constant.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +struct _LIBCPP_NO_SPECIALIZATIONS is_empty : integral_constant {}; + +#if _LIBCPP_STD_VER >= 17 +template +_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_empty_v = __is_empty(_Tp); +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_IS_EMPTY_H diff --git a/src/include/__type_traits/is_enum.h b/src/include/__type_traits/is_enum.h new file mode 100644 index 0000000..4a58b19 --- /dev/null +++ b/src/include/__type_traits/is_enum.h @@ -0,0 +1,41 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_IS_ENUM_H +#define _LIBCPP___TYPE_TRAITS_IS_ENUM_H + +#include <__config> +#include <__type_traits/integral_constant.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +struct _LIBCPP_NO_SPECIALIZATIONS is_enum : integral_constant {}; + +#if _LIBCPP_STD_VER >= 17 +template +_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_enum_v = __is_enum(_Tp); +#endif + +#if _LIBCPP_STD_VER >= 23 + +template +struct _LIBCPP_NO_SPECIALIZATIONS is_scoped_enum : bool_constant<__is_scoped_enum(_Tp)> {}; + +template +_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_scoped_enum_v = __is_scoped_enum(_Tp); + +#endif // _LIBCPP_STD_VER >= 23 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_IS_ENUM_H diff --git a/src/include/__type_traits/is_equality_comparable.h b/src/include/__type_traits/is_equality_comparable.h new file mode 100644 index 0000000..3ee1839 --- /dev/null +++ b/src/include/__type_traits/is_equality_comparable.h @@ -0,0 +1,88 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_IS_EQUALITY_COMPARABLE_H +#define _LIBCPP___TYPE_TRAITS_IS_EQUALITY_COMPARABLE_H + +#include <__config> +#include <__type_traits/enable_if.h> +#include <__type_traits/integral_constant.h> +#include <__type_traits/is_integral.h> +#include <__type_traits/is_same.h> +#include <__type_traits/is_signed.h> +#include <__type_traits/is_void.h> +#include <__type_traits/remove_cv.h> +#include <__type_traits/void_t.h> +#include <__utility/declval.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +struct __is_equality_comparable : false_type {}; + +template +struct __is_equality_comparable<_Tp, _Up, __void_t() == std::declval<_Up>())> > : true_type { +}; + +// A type is_trivially_equality_comparable if the expression `a == b` is equivalent to `std::memcmp(&a, &b, sizeof(T))` +// (with `a` and `b` being of type `T`). For the case where we compare two object of the same type, we can use +// __is_trivially_equality_comparable. We have special-casing for pointers which point to the same type ignoring +// cv-qualifications and comparing to void-pointers. +// +// The following types are not trivially equality comparable: +// floating-point types: different bit-patterns can compare equal. (e.g 0.0 and -0.0) +// enums: The user is allowed to specialize operator== for enums +// pointers that don't have the same type (ignoring cv-qualifiers): pointers to virtual bases are equality comparable, +// but don't have the same bit-pattern. An exception to this is comparing to a void-pointer. There the bit-pattern is +// always compared. +// objects with padding bytes: since objects with padding bytes may compare equal, even though their object +// representation may not be equivalent. + +template +struct __libcpp_is_trivially_equality_comparable_impl : false_type {}; + +template +struct __libcpp_is_trivially_equality_comparable_impl<_Tp, _Tp> +#if __has_builtin(__is_trivially_equality_comparable) + : integral_constant::value> { +}; +#else + : is_integral<_Tp> { +}; +#endif // __has_builtin(__is_trivially_equality_comparable) + +template +struct __libcpp_is_trivially_equality_comparable_impl< + _Tp, + _Up, + __enable_if_t::value && is_integral<_Up>::value && !is_same<_Tp, _Up>::value && + is_signed<_Tp>::value == is_signed<_Up>::value && sizeof(_Tp) == sizeof(_Up)> > : true_type {}; + +template +struct __libcpp_is_trivially_equality_comparable_impl<_Tp*, _Tp*> : true_type {}; + +// TODO: Use is_pointer_inverconvertible_base_of +template +struct __libcpp_is_trivially_equality_comparable_impl<_Tp*, _Up*> + : integral_constant< + bool, + __is_equality_comparable<_Tp*, _Up*>::value && + (is_same<__remove_cv_t<_Tp>, __remove_cv_t<_Up> >::value || is_void<_Tp>::value || is_void<_Up>::value)> { +}; + +template +using __libcpp_is_trivially_equality_comparable _LIBCPP_NODEBUG = + __libcpp_is_trivially_equality_comparable_impl<__remove_cv_t<_Tp>, __remove_cv_t<_Up> >; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_IS_EQUALITY_COMPARABLE_H diff --git a/src/include/__type_traits/is_execution_policy.h b/src/include/__type_traits/is_execution_policy.h new file mode 100644 index 0000000..84393e8 --- /dev/null +++ b/src/include/__type_traits/is_execution_policy.h @@ -0,0 +1,59 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_IS_EXECUTION_POLICY_H +#define _LIBCPP___TYPE_TRAITS_IS_EXECUTION_POLICY_H + +#include <__config> +#include <__type_traits/remove_cvref.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER >= 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_execution_policy_v = false; + +template +inline constexpr bool __is_unsequenced_execution_policy_impl = false; + +template +inline constexpr bool __is_unsequenced_execution_policy_v = + __is_unsequenced_execution_policy_impl<__remove_cvref_t<_Tp>>; + +template +inline constexpr bool __is_parallel_execution_policy_impl = false; + +template +inline constexpr bool __is_parallel_execution_policy_v = __is_parallel_execution_policy_impl<__remove_cvref_t<_Tp>>; + +namespace execution { +struct __disable_user_instantiations_tag { + explicit __disable_user_instantiations_tag() = default; +}; +} // namespace execution + +// TODO: Remove default argument once algorithms are using the new backend dispatching +template +_LIBCPP_HIDE_FROM_ABI auto +__remove_parallel_policy(const _ExecutionPolicy& = _ExecutionPolicy{execution::__disable_user_instantiations_tag{}}); + +// Removes the "parallel" part of an execution policy. +// For example, turns par_unseq into unseq, and par into seq. +template +using __remove_parallel_policy_t _LIBCPP_NODEBUG = decltype(std::__remove_parallel_policy<_ExecutionPolicy>()); + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER >= 17 + +#endif // _LIBCPP___TYPE_TRAITS_IS_EXECUTION_POLICY_H diff --git a/src/include/__type_traits/is_final.h b/src/include/__type_traits/is_final.h new file mode 100644 index 0000000..e9ef142 --- /dev/null +++ b/src/include/__type_traits/is_final.h @@ -0,0 +1,36 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_IS_FINAL_H +#define _LIBCPP___TYPE_TRAITS_IS_FINAL_H + +#include <__config> +#include <__type_traits/integral_constant.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +struct __libcpp_is_final : integral_constant {}; + +#if _LIBCPP_STD_VER >= 14 +template +struct _LIBCPP_NO_SPECIALIZATIONS is_final : integral_constant {}; +#endif + +#if _LIBCPP_STD_VER >= 17 +template +_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_final_v = __is_final(_Tp); +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_IS_FINAL_H diff --git a/src/include/__type_traits/is_floating_point.h b/src/include/__type_traits/is_floating_point.h new file mode 100644 index 0000000..b87363f --- /dev/null +++ b/src/include/__type_traits/is_floating_point.h @@ -0,0 +1,39 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_IS_FLOATING_POINT_H +#define _LIBCPP___TYPE_TRAITS_IS_FLOATING_POINT_H + +#include <__config> +#include <__type_traits/integral_constant.h> +#include <__type_traits/remove_cv.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +// clang-format off +template struct __libcpp_is_floating_point : false_type {}; +template <> struct __libcpp_is_floating_point : true_type {}; +template <> struct __libcpp_is_floating_point : true_type {}; +template <> struct __libcpp_is_floating_point : true_type {}; +// clang-format on + +template +struct _LIBCPP_NO_SPECIALIZATIONS is_floating_point : __libcpp_is_floating_point<__remove_cv_t<_Tp> > {}; + +#if _LIBCPP_STD_VER >= 17 +template +_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_floating_point_v = is_floating_point<_Tp>::value; +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_IS_FLOATING_POINT_H diff --git a/src/include/__type_traits/is_function.h b/src/include/__type_traits/is_function.h new file mode 100644 index 0000000..119892e --- /dev/null +++ b/src/include/__type_traits/is_function.h @@ -0,0 +1,31 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_IS_FUNCTIONAL_H +#define _LIBCPP___TYPE_TRAITS_IS_FUNCTIONAL_H + +#include <__config> +#include <__type_traits/integral_constant.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +struct _LIBCPP_NO_SPECIALIZATIONS is_function : integral_constant {}; + +#if _LIBCPP_STD_VER >= 17 +template +_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_function_v = __is_function(_Tp); +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_IS_FUNCTIONAL_H diff --git a/src/include/__type_traits/is_fundamental.h b/src/include/__type_traits/is_fundamental.h new file mode 100644 index 0000000..6236553 --- /dev/null +++ b/src/include/__type_traits/is_fundamental.h @@ -0,0 +1,48 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_IS_FUNDAMENTAL_H +#define _LIBCPP___TYPE_TRAITS_IS_FUNDAMENTAL_H + +#include <__config> +#include <__type_traits/integral_constant.h> +#include <__type_traits/is_null_pointer.h> +#include <__type_traits/is_void.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if __has_builtin(__is_fundamental) + +template +struct _LIBCPP_NO_SPECIALIZATIONS is_fundamental : _BoolConstant<__is_fundamental(_Tp)> {}; + +# if _LIBCPP_STD_VER >= 17 +template +_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_fundamental_v = __is_fundamental(_Tp); +# endif + +#else // __has_builtin(__is_fundamental) + +template +struct is_fundamental + : integral_constant::value || __is_null_pointer_v<_Tp> || is_arithmetic<_Tp>::value> {}; + +# if _LIBCPP_STD_VER >= 17 +template +inline constexpr bool is_fundamental_v = is_fundamental<_Tp>::value; +# endif + +#endif // __has_builtin(__is_fundamental) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_IS_FUNDAMENTAL_H diff --git a/src/include/__type_traits/is_implicit_lifetime.h b/src/include/__type_traits/is_implicit_lifetime.h new file mode 100644 index 0000000..e5d1c05 --- /dev/null +++ b/src/include/__type_traits/is_implicit_lifetime.h @@ -0,0 +1,35 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_IS_IMPLICIT_LIFETIME_H +#define _LIBCPP___TYPE_TRAITS_IS_IMPLICIT_LIFETIME_H + +#include <__config> +#include <__type_traits/integral_constant.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER >= 23 +# if __has_builtin(__builtin_is_implicit_lifetime) + +template +struct _LIBCPP_NO_SPECIALIZATIONS is_implicit_lifetime : bool_constant<__builtin_is_implicit_lifetime(_Tp)> {}; + +template +_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_implicit_lifetime_v = __builtin_is_implicit_lifetime(_Tp); + +# endif +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_IS_IMPLICIT_LIFETIME_H diff --git a/src/include/__type_traits/is_implicitly_default_constructible.h b/src/include/__type_traits/is_implicitly_default_constructible.h new file mode 100644 index 0000000..d5dadd7 --- /dev/null +++ b/src/include/__type_traits/is_implicitly_default_constructible.h @@ -0,0 +1,46 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_IS_IMPLICITLY_DEFAULT_CONSTRUCTIBLE_H +#define _LIBCPP___TYPE_TRAITS_IS_IMPLICITLY_DEFAULT_CONSTRUCTIBLE_H + +#include <__config> +#include <__type_traits/integral_constant.h> +#include <__type_traits/is_constructible.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#ifndef _LIBCPP_CXX03_LANG +// First of all, we can't implement this check in C++03 mode because the {} +// default initialization syntax isn't valid. +// Second, we implement the trait in a funny manner with two defaulted template +// arguments to workaround Clang's PR43454. +template +void __test_implicit_default_constructible(_Tp); + +template ::type> +struct __is_implicitly_default_constructible : false_type {}; + +template +struct __is_implicitly_default_constructible<_Tp, + decltype(std::__test_implicit_default_constructible<_Tp const&>({})), + true_type> : true_type {}; + +template +struct __is_implicitly_default_constructible<_Tp, + decltype(std::__test_implicit_default_constructible<_Tp const&>({})), + false_type> : false_type {}; +#endif // !C++03 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_IS_IMPLICITLY_DEFAULT_CONSTRUCTIBLE_H diff --git a/src/include/__type_traits/is_integral.h b/src/include/__type_traits/is_integral.h new file mode 100644 index 0000000..7f7ac26 --- /dev/null +++ b/src/include/__type_traits/is_integral.h @@ -0,0 +1,74 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_IS_INTEGRAL_H +#define _LIBCPP___TYPE_TRAITS_IS_INTEGRAL_H + +#include <__config> +#include <__type_traits/integral_constant.h> +#include <__type_traits/remove_cv.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +// clang-format off +template struct __libcpp_is_integral { enum { value = 0 }; }; +template <> struct __libcpp_is_integral { enum { value = 1 }; }; +template <> struct __libcpp_is_integral { enum { value = 1 }; }; +template <> struct __libcpp_is_integral { enum { value = 1 }; }; +template <> struct __libcpp_is_integral { enum { value = 1 }; }; +#if _LIBCPP_HAS_WIDE_CHARACTERS +template <> struct __libcpp_is_integral { enum { value = 1 }; }; +#endif +#if _LIBCPP_HAS_CHAR8_T +template <> struct __libcpp_is_integral { enum { value = 1 }; }; +#endif +template <> struct __libcpp_is_integral { enum { value = 1 }; }; +template <> struct __libcpp_is_integral { enum { value = 1 }; }; +template <> struct __libcpp_is_integral { enum { value = 1 }; }; +template <> struct __libcpp_is_integral { enum { value = 1 }; }; +template <> struct __libcpp_is_integral { enum { value = 1 }; }; +template <> struct __libcpp_is_integral { enum { value = 1 }; }; +template <> struct __libcpp_is_integral { enum { value = 1 }; }; +template <> struct __libcpp_is_integral { enum { value = 1 }; }; +template <> struct __libcpp_is_integral { enum { value = 1 }; }; +template <> struct __libcpp_is_integral { enum { value = 1 }; }; +#if _LIBCPP_HAS_INT128 +template <> struct __libcpp_is_integral<__int128_t> { enum { value = 1 }; }; +template <> struct __libcpp_is_integral<__uint128_t> { enum { value = 1 }; }; +#endif +// clang-format on + +#if __has_builtin(__is_integral) + +template +struct _LIBCPP_NO_SPECIALIZATIONS is_integral : _BoolConstant<__is_integral(_Tp)> {}; + +# if _LIBCPP_STD_VER >= 17 +template +_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_integral_v = __is_integral(_Tp); +# endif + +#else + +template +struct is_integral : public _BoolConstant<__libcpp_is_integral<__remove_cv_t<_Tp> >::value> {}; + +# if _LIBCPP_STD_VER >= 17 +template +inline constexpr bool is_integral_v = is_integral<_Tp>::value; +# endif + +#endif // __has_builtin(__is_integral) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_IS_INTEGRAL_H diff --git a/src/include/__type_traits/is_literal_type.h b/src/include/__type_traits/is_literal_type.h new file mode 100644 index 0000000..2e0df3a --- /dev/null +++ b/src/include/__type_traits/is_literal_type.h @@ -0,0 +1,34 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_IS_LITERAL_TYPE +#define _LIBCPP___TYPE_TRAITS_IS_LITERAL_TYPE + +#include <__config> +#include <__type_traits/integral_constant.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS) +template +struct _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_NO_SPECIALIZATIONS is_literal_type + : integral_constant {}; + +# if _LIBCPP_STD_VER >= 17 +template +_LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_literal_type_v = __is_literal_type(_Tp); +# endif // _LIBCPP_STD_VER >= 17 +#endif // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_IS_LITERAL_TYPE diff --git a/src/include/__type_traits/is_member_pointer.h b/src/include/__type_traits/is_member_pointer.h new file mode 100644 index 0000000..e4fd9e0 --- /dev/null +++ b/src/include/__type_traits/is_member_pointer.h @@ -0,0 +1,43 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_IS_MEMBER_POINTER_H +#define _LIBCPP___TYPE_TRAITS_IS_MEMBER_POINTER_H + +#include <__config> +#include <__type_traits/integral_constant.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +struct _LIBCPP_NO_SPECIALIZATIONS is_member_pointer : _BoolConstant<__is_member_pointer(_Tp)> {}; + +template +struct _LIBCPP_NO_SPECIALIZATIONS is_member_object_pointer : _BoolConstant<__is_member_object_pointer(_Tp)> {}; + +template +struct _LIBCPP_NO_SPECIALIZATIONS is_member_function_pointer : _BoolConstant<__is_member_function_pointer(_Tp)> {}; + +#if _LIBCPP_STD_VER >= 17 +template +_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_member_pointer_v = __is_member_pointer(_Tp); + +template +_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_member_object_pointer_v = __is_member_object_pointer(_Tp); + +template +_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_member_function_pointer_v = __is_member_function_pointer(_Tp); +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_IS_MEMBER_POINTER_H diff --git a/src/include/__type_traits/is_nothrow_assignable.h b/src/include/__type_traits/is_nothrow_assignable.h new file mode 100644 index 0000000..903dead --- /dev/null +++ b/src/include/__type_traits/is_nothrow_assignable.h @@ -0,0 +1,53 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_IS_NOTHROW_ASSIGNABLE_H +#define _LIBCPP___TYPE_TRAITS_IS_NOTHROW_ASSIGNABLE_H + +#include <__config> +#include <__type_traits/add_lvalue_reference.h> +#include <__type_traits/add_rvalue_reference.h> +#include <__type_traits/integral_constant.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +struct _LIBCPP_NO_SPECIALIZATIONS is_nothrow_assignable : integral_constant { +}; + +#if _LIBCPP_STD_VER >= 17 +template +_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_nothrow_assignable_v = __is_nothrow_assignable(_Tp, _Arg); +#endif + +template +struct _LIBCPP_NO_SPECIALIZATIONS is_nothrow_copy_assignable + : integral_constant, __add_lvalue_reference_t)> {}; + +#if _LIBCPP_STD_VER >= 17 +template +_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_nothrow_copy_assignable_v = is_nothrow_copy_assignable<_Tp>::value; +#endif + +template +struct _LIBCPP_NO_SPECIALIZATIONS is_nothrow_move_assignable + : integral_constant, __add_rvalue_reference_t<_Tp>)> {}; + +#if _LIBCPP_STD_VER >= 17 +template +_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_nothrow_move_assignable_v = is_nothrow_move_assignable<_Tp>::value; +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_IS_NOTHROW_ASSIGNABLE_H diff --git a/src/include/__type_traits/is_nothrow_constructible.h b/src/include/__type_traits/is_nothrow_constructible.h new file mode 100644 index 0000000..bd14c1c --- /dev/null +++ b/src/include/__type_traits/is_nothrow_constructible.h @@ -0,0 +1,64 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_IS_NOTHROW_CONSTRUCTIBLE_H +#define _LIBCPP___TYPE_TRAITS_IS_NOTHROW_CONSTRUCTIBLE_H + +#include <__config> +#include <__type_traits/add_lvalue_reference.h> +#include <__type_traits/add_rvalue_reference.h> +#include <__type_traits/integral_constant.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template < class _Tp, class... _Args> +struct _LIBCPP_NO_SPECIALIZATIONS is_nothrow_constructible + : integral_constant {}; + +#if _LIBCPP_STD_VER >= 17 +template +_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_nothrow_constructible_v = + is_nothrow_constructible<_Tp, _Args...>::value; +#endif + +template +struct _LIBCPP_NO_SPECIALIZATIONS is_nothrow_copy_constructible + : integral_constant)> {}; + +#if _LIBCPP_STD_VER >= 17 +template +_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_nothrow_copy_constructible_v = + is_nothrow_copy_constructible<_Tp>::value; +#endif + +template +struct _LIBCPP_NO_SPECIALIZATIONS is_nothrow_move_constructible + : integral_constant)> {}; + +#if _LIBCPP_STD_VER >= 17 +template +_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_nothrow_move_constructible_v = + is_nothrow_move_constructible<_Tp>::value; +#endif + +template +struct _LIBCPP_NO_SPECIALIZATIONS is_nothrow_default_constructible + : integral_constant {}; + +#if _LIBCPP_STD_VER >= 17 +template +_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_nothrow_default_constructible_v = __is_nothrow_constructible(_Tp); +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_IS_NOTHROW_CONSTRUCTIBLE_H diff --git a/src/include/__type_traits/is_nothrow_destructible.h b/src/include/__type_traits/is_nothrow_destructible.h new file mode 100644 index 0000000..81a34f9 --- /dev/null +++ b/src/include/__type_traits/is_nothrow_destructible.h @@ -0,0 +1,61 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_IS_NOTHROW_DESTRUCTIBLE_H +#define _LIBCPP___TYPE_TRAITS_IS_NOTHROW_DESTRUCTIBLE_H + +#include <__config> +#include <__cstddef/size_t.h> +#include <__type_traits/integral_constant.h> +#include <__type_traits/is_destructible.h> +#include <__utility/declval.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if __has_builtin(__is_nothrow_destructible) + +template +struct _LIBCPP_NO_SPECIALIZATIONS is_nothrow_destructible : integral_constant {}; + +#else + +template +struct __libcpp_is_nothrow_destructible; + +template +struct __libcpp_is_nothrow_destructible : false_type {}; + +template +struct __libcpp_is_nothrow_destructible : integral_constant().~_Tp()) > {}; + +template +struct is_nothrow_destructible : __libcpp_is_nothrow_destructible::value, _Tp> {}; + +template +struct is_nothrow_destructible<_Tp[_Ns]> : is_nothrow_destructible<_Tp> {}; + +template +struct is_nothrow_destructible<_Tp&> : true_type {}; + +template +struct is_nothrow_destructible<_Tp&&> : true_type {}; + +#endif // __has_builtin(__is_nothrow_destructible) + +#if _LIBCPP_STD_VER >= 17 +template +_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_nothrow_destructible_v = is_nothrow_destructible<_Tp>::value; +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_IS_NOTHROW_DESTRUCTIBLE_H diff --git a/src/include/__type_traits/is_null_pointer.h b/src/include/__type_traits/is_null_pointer.h new file mode 100644 index 0000000..63bfb7d --- /dev/null +++ b/src/include/__type_traits/is_null_pointer.h @@ -0,0 +1,37 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_IS_NULL_POINTER_H +#define _LIBCPP___TYPE_TRAITS_IS_NULL_POINTER_H + +#include <__config> +#include <__cstddef/nullptr_t.h> +#include <__type_traits/integral_constant.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +inline const bool __is_null_pointer_v = __is_same(__remove_cv(_Tp), nullptr_t); + +#if _LIBCPP_STD_VER >= 14 +template +struct _LIBCPP_NO_SPECIALIZATIONS is_null_pointer : integral_constant> {}; + +# if _LIBCPP_STD_VER >= 17 +template +_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_null_pointer_v = __is_null_pointer_v<_Tp>; +# endif +#endif // _LIBCPP_STD_VER >= 14 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_IS_NULL_POINTER_H diff --git a/src/include/__type_traits/is_object.h b/src/include/__type_traits/is_object.h new file mode 100644 index 0000000..6532835 --- /dev/null +++ b/src/include/__type_traits/is_object.h @@ -0,0 +1,31 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_IS_OBJECT_H +#define _LIBCPP___TYPE_TRAITS_IS_OBJECT_H + +#include <__config> +#include <__type_traits/integral_constant.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +struct _LIBCPP_NO_SPECIALIZATIONS is_object : _BoolConstant<__is_object(_Tp)> {}; + +#if _LIBCPP_STD_VER >= 17 +template +_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_object_v = __is_object(_Tp); +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_IS_OBJECT_H diff --git a/src/include/__type_traits/is_pod.h b/src/include/__type_traits/is_pod.h new file mode 100644 index 0000000..8b805e9 --- /dev/null +++ b/src/include/__type_traits/is_pod.h @@ -0,0 +1,31 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_IS_POD_H +#define _LIBCPP___TYPE_TRAITS_IS_POD_H + +#include <__config> +#include <__type_traits/integral_constant.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +struct _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_NO_SPECIALIZATIONS is_pod : integral_constant {}; + +#if _LIBCPP_STD_VER >= 17 +template +_LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_pod_v = __is_pod(_Tp); +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_IS_POD_H diff --git a/src/include/__type_traits/is_pointer.h b/src/include/__type_traits/is_pointer.h new file mode 100644 index 0000000..7bc78a6 --- /dev/null +++ b/src/include/__type_traits/is_pointer.h @@ -0,0 +1,64 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_IS_POINTER_H +#define _LIBCPP___TYPE_TRAITS_IS_POINTER_H + +#include <__config> +#include <__type_traits/integral_constant.h> +#include <__type_traits/remove_cv.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if __has_builtin(__is_pointer) + +template +struct _LIBCPP_NO_SPECIALIZATIONS is_pointer : _BoolConstant<__is_pointer(_Tp)> {}; + +# if _LIBCPP_STD_VER >= 17 +template +_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_pointer_v = __is_pointer(_Tp); +# endif + +#else // __has_builtin(__is_pointer) + +template +struct __libcpp_is_pointer : false_type {}; +template +struct __libcpp_is_pointer<_Tp*> : true_type {}; + +template +struct __libcpp_remove_objc_qualifiers { + typedef _Tp type; +}; +# if _LIBCPP_HAS_OBJC_ARC +// clang-format off +template struct __libcpp_remove_objc_qualifiers<_Tp __strong> { typedef _Tp type; }; +template struct __libcpp_remove_objc_qualifiers<_Tp __weak> { typedef _Tp type; }; +template struct __libcpp_remove_objc_qualifiers<_Tp __autoreleasing> { typedef _Tp type; }; +template struct __libcpp_remove_objc_qualifiers<_Tp __unsafe_unretained> { typedef _Tp type; }; +// clang-format on +# endif + +template +struct is_pointer : __libcpp_is_pointer >::type> {}; + +# if _LIBCPP_STD_VER >= 17 +template +inline constexpr bool is_pointer_v = is_pointer<_Tp>::value; +# endif + +#endif // __has_builtin(__is_pointer) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_IS_POINTER_H diff --git a/src/include/__type_traits/is_polymorphic.h b/src/include/__type_traits/is_polymorphic.h new file mode 100644 index 0000000..4ced8ec --- /dev/null +++ b/src/include/__type_traits/is_polymorphic.h @@ -0,0 +1,31 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_IS_POLYMORPHIC_H +#define _LIBCPP___TYPE_TRAITS_IS_POLYMORPHIC_H + +#include <__config> +#include <__type_traits/integral_constant.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +struct _LIBCPP_NO_SPECIALIZATIONS is_polymorphic : integral_constant {}; + +#if _LIBCPP_STD_VER >= 17 +template +_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_polymorphic_v = __is_polymorphic(_Tp); +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_IS_POLYMORPHIC_H diff --git a/src/include/__type_traits/is_primary_template.h b/src/include/__type_traits/is_primary_template.h new file mode 100644 index 0000000..5fe6820 --- /dev/null +++ b/src/include/__type_traits/is_primary_template.h @@ -0,0 +1,32 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_IS_PRIMARY_TEMPLATE_H +#define _LIBCPP___TYPE_TRAITS_IS_PRIMARY_TEMPLATE_H + +#include <__config> +#include <__type_traits/enable_if.h> +#include <__type_traits/is_same.h> +#include <__type_traits/is_valid_expansion.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +using __test_for_primary_template _LIBCPP_NODEBUG = + __enable_if_t<_IsSame<_Tp, typename _Tp::__primary_template>::value>; + +template +using __is_primary_template _LIBCPP_NODEBUG = _IsValidExpansion<__test_for_primary_template, _Tp>; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_IS_PRIMARY_TEMPLATE_H diff --git a/src/include/__type_traits/is_reference.h b/src/include/__type_traits/is_reference.h new file mode 100644 index 0000000..9c98c13 --- /dev/null +++ b/src/include/__type_traits/is_reference.h @@ -0,0 +1,68 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_IS_REFERENCE_H +#define _LIBCPP___TYPE_TRAITS_IS_REFERENCE_H + +#include <__config> +#include <__type_traits/integral_constant.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +struct _LIBCPP_NO_SPECIALIZATIONS is_reference : _BoolConstant<__is_reference(_Tp)> {}; + +#if _LIBCPP_STD_VER >= 17 +template +_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_reference_v = __is_reference(_Tp); +#endif + +#if __has_builtin(__is_lvalue_reference) && __has_builtin(__is_rvalue_reference) + +template +struct _LIBCPP_NO_SPECIALIZATIONS is_lvalue_reference : _BoolConstant<__is_lvalue_reference(_Tp)> {}; + +template +struct _LIBCPP_NO_SPECIALIZATIONS is_rvalue_reference : _BoolConstant<__is_rvalue_reference(_Tp)> {}; + +# if _LIBCPP_STD_VER >= 17 +template +_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_lvalue_reference_v = __is_lvalue_reference(_Tp); +template +_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_rvalue_reference_v = __is_rvalue_reference(_Tp); +# endif + +#else // __has_builtin(__is_lvalue_reference) + +template +struct is_lvalue_reference : false_type {}; +template +struct is_lvalue_reference<_Tp&> : true_type {}; + +template +struct is_rvalue_reference : false_type {}; +template +struct is_rvalue_reference<_Tp&&> : true_type {}; + +# if _LIBCPP_STD_VER >= 17 +template +inline constexpr bool is_lvalue_reference_v = is_lvalue_reference<_Tp>::value; + +template +inline constexpr bool is_rvalue_reference_v = is_rvalue_reference<_Tp>::value; +# endif + +#endif // __has_builtin(__is_lvalue_reference) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_IS_REFERENCE_H diff --git a/src/include/__type_traits/is_reference_wrapper.h b/src/include/__type_traits/is_reference_wrapper.h new file mode 100644 index 0000000..4bd8ebd --- /dev/null +++ b/src/include/__type_traits/is_reference_wrapper.h @@ -0,0 +1,32 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_IS_REFERENCE_WRAPPER_H +#define _LIBCPP___TYPE_TRAITS_IS_REFERENCE_WRAPPER_H + +#include <__config> +#include <__fwd/functional.h> +#include <__type_traits/integral_constant.h> +#include <__type_traits/remove_cv.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +struct __is_reference_wrapper_impl : false_type {}; +template +struct __is_reference_wrapper_impl > : true_type {}; +template +struct __is_reference_wrapper : __is_reference_wrapper_impl<__remove_cv_t<_Tp> > {}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_ENABLE_IF_H diff --git a/src/include/__type_traits/is_referenceable.h b/src/include/__type_traits/is_referenceable.h new file mode 100644 index 0000000..3a9d285 --- /dev/null +++ b/src/include/__type_traits/is_referenceable.h @@ -0,0 +1,34 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_IS_REFERENCEABLE_H +#define _LIBCPP___TYPE_TRAITS_IS_REFERENCEABLE_H + +#include <__config> +#include <__type_traits/void_t.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +inline const bool __is_referenceable_v = false; + +template +inline const bool __is_referenceable_v<_Tp, __void_t<_Tp&> > = true; + +#if _LIBCPP_STD_VER >= 20 +template +concept __referenceable = __is_referenceable_v<_Tp>; +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_IS_REFERENCEABLE_H diff --git a/src/include/__type_traits/is_replaceable.h b/src/include/__type_traits/is_replaceable.h new file mode 100644 index 0000000..e1d17c0 --- /dev/null +++ b/src/include/__type_traits/is_replaceable.h @@ -0,0 +1,61 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_IS_REPLACEABLE_H +#define _LIBCPP___TYPE_TRAITS_IS_REPLACEABLE_H + +#include <__config> +#include <__type_traits/enable_if.h> +#include <__type_traits/integral_constant.h> +#include <__type_traits/is_same.h> +#include <__type_traits/is_trivially_copyable.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +// A type is replaceable if, with `x` and `y` being different objects, `x = std::move(y)` is equivalent to: +// +// std::destroy_at(&x) +// std::construct_at(&x, std::move(y)) +// +// This allows turning a move-assignment into a sequence of destroy + move-construct, which +// is often more efficient. This is especially relevant when the move-construct is in fact +// part of a trivial relocation from somewhere else, in which case there is a huge win. +// +// Note that this requires language support in order to be really effective, but we +// currently emulate the base template with something very conservative. +template +struct __is_replaceable : is_trivially_copyable<_Tp> {}; + +template +struct __is_replaceable<_Tp, __enable_if_t::value> > : true_type {}; + +template +inline const bool __is_replaceable_v = __is_replaceable<_Tp>::value; + +// Determines whether an allocator member of a container is replaceable. +// +// First, we require the allocator type to be considered replaceable. If not, then something fishy might be +// happening. Assuming the allocator type is replaceable, we conclude replaceability of the allocator as a +// member of the container if the allocator always compares equal (in which case propagation doesn't matter), +// or if the allocator always propagates on assignment, which is required in order for move construction and +// assignment to be equivalent. +template +struct __container_allocator_is_replaceable + : integral_constant && + (_AllocatorTraits::is_always_equal::value || + (_AllocatorTraits::propagate_on_container_move_assignment::value && + _AllocatorTraits::propagate_on_container_copy_assignment::value))> {}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_IS_REPLACEABLE_H diff --git a/src/include/__type_traits/is_same.h b/src/include/__type_traits/is_same.h new file mode 100644 index 0000000..a5e95f2 --- /dev/null +++ b/src/include/__type_traits/is_same.h @@ -0,0 +1,41 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_IS_SAME_H +#define _LIBCPP___TYPE_TRAITS_IS_SAME_H + +#include <__type_traits/integral_constant.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + + +template +struct is_same : _BoolConstant<__is_same(_Tp, _Up)> {}; + +#if _LIBCPP_STD_VER >= 17 +template +_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_same_v = __is_same(_Tp, _Up); +#endif + +// _IsSame has the same effect as is_same but instantiates fewer types: +// is_same and is_same are guaranteed to be different types, but +// _IsSame and _IsSame are the same type (namely, false_type). +// Neither GCC nor Clang can mangle the __is_same builtin, so _IsSame +// mustn't be directly used anywhere that contributes to name-mangling +// (such as in a dependent return type). + +template +using _IsSame = _BoolConstant<__is_same(_Tp, _Up)>; + +template +using _IsNotSame = _BoolConstant; + + +#endif // _LIBCPP___TYPE_TRAITS_IS_SAME_H diff --git a/src/include/__type_traits/is_scalar.h b/src/include/__type_traits/is_scalar.h new file mode 100644 index 0000000..102a0ca --- /dev/null +++ b/src/include/__type_traits/is_scalar.h @@ -0,0 +1,69 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_IS_SCALAR_H +#define _LIBCPP___TYPE_TRAITS_IS_SCALAR_H + +#include <__config> +#include <__type_traits/integral_constant.h> +#include <__type_traits/is_arithmetic.h> +#include <__type_traits/is_enum.h> +#include <__type_traits/is_member_pointer.h> +#include <__type_traits/is_null_pointer.h> +#include <__type_traits/is_pointer.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if __has_builtin(__is_scalar) + +template +struct _LIBCPP_NO_SPECIALIZATIONS is_scalar : _BoolConstant<__is_scalar(_Tp)> {}; + +# if _LIBCPP_STD_VER >= 17 +template +_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_scalar_v = __is_scalar(_Tp); +# endif + +#else // __has_builtin(__is_scalar) + +template +struct __is_block : false_type {}; +# if _LIBCPP_HAS_EXTENSION_BLOCKS +template +struct __is_block<_Rp (^)(_Args...)> : true_type {}; +# endif + +// clang-format off +template +struct is_scalar + : integral_constant< + bool, is_arithmetic<_Tp>::value || + is_member_pointer<_Tp>::value || + is_pointer<_Tp>::value || + __is_null_pointer_v<_Tp> || + __is_block<_Tp>::value || + is_enum<_Tp>::value> {}; +// clang-format on + +template <> +struct is_scalar : true_type {}; + +# if _LIBCPP_STD_VER >= 17 +template +inline constexpr bool is_scalar_v = is_scalar<_Tp>::value; +# endif + +#endif // __has_builtin(__is_scalar) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_IS_SCALAR_H diff --git a/src/include/__type_traits/is_signed.h b/src/include/__type_traits/is_signed.h new file mode 100644 index 0000000..02f51f9 --- /dev/null +++ b/src/include/__type_traits/is_signed.h @@ -0,0 +1,52 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_IS_SIGNED_H +#define _LIBCPP___TYPE_TRAITS_IS_SIGNED_H + +#include <__config> +#include <__type_traits/integral_constant.h> +#include <__type_traits/is_arithmetic.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if __has_builtin(__is_signed) + +template +struct _LIBCPP_NO_SPECIALIZATIONS is_signed : _BoolConstant<__is_signed(_Tp)> {}; + +# if _LIBCPP_STD_VER >= 17 +template +_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_signed_v = __is_signed(_Tp); +# endif + +#else // __has_builtin(__is_signed) + +template ::value> +inline constexpr bool __is_signed_v = false; + +template +inline constexpr bool __is_signed_v<_Tp, true> = _Tp(-1) < _Tp(0); + +template +struct is_signed : integral_constant> {}; + +# if _LIBCPP_STD_VER >= 17 +template +inline constexpr bool is_signed_v = __is_signed_v<_Tp>; +# endif + +#endif // __has_builtin(__is_signed) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_IS_SIGNED_H diff --git a/src/include/__type_traits/is_signed_integer.h b/src/include/__type_traits/is_signed_integer.h new file mode 100644 index 0000000..6294390 --- /dev/null +++ b/src/include/__type_traits/is_signed_integer.h @@ -0,0 +1,35 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_IS_SIGNED_INTEGER_H +#define _LIBCPP___TYPE_TRAITS_IS_SIGNED_INTEGER_H + +#include <__config> +#include <__type_traits/integral_constant.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +// clang-format off +template struct __libcpp_is_signed_integer : false_type {}; +template <> struct __libcpp_is_signed_integer : true_type {}; +template <> struct __libcpp_is_signed_integer : true_type {}; +template <> struct __libcpp_is_signed_integer : true_type {}; +template <> struct __libcpp_is_signed_integer : true_type {}; +template <> struct __libcpp_is_signed_integer : true_type {}; +#if _LIBCPP_HAS_INT128 +template <> struct __libcpp_is_signed_integer<__int128_t> : true_type {}; +#endif +// clang-format on + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_IS_SIGNED_INTEGER_H diff --git a/src/include/__type_traits/is_specialization.h b/src/include/__type_traits/is_specialization.h new file mode 100644 index 0000000..9b75636 --- /dev/null +++ b/src/include/__type_traits/is_specialization.h @@ -0,0 +1,45 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___TYPE_TRAITS_IS_SPECIALIZATION +#define _LIBCPP___TYPE_TRAITS_IS_SPECIALIZATION + +// This contains parts of P2098R1 but is based on MSVC STL's implementation. +// +// The paper has been rejected +// We will not pursue P2098R0 (std::is_specialization_of) at this time; we'd +// like to see a solution to this problem, but it requires language evolution +// too. +// +// Since it is expected a real solution will be provided in the future only the +// minimal part is implemented. +// +// Note a cvref qualified _Tp is never considered a specialization. + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER >= 17 + +template class _Template> +inline constexpr bool __is_specialization_v = false; // true if and only if _Tp is a specialization of _Template + +template