mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-25 14:50:26 +00:00
[libc++] Implements concept default_initializable.
Implements: - LWG3149 DefaultConstructible should require default initialization Implements parts of: - P0898R3 Standard Library Concepts - P1754 Rename concepts to standard_case for C++20, while we still can Depends on D91986 Reviewed By: ldionne, #libc Differential Revision: https://reviews.llvm.org/D93461
This commit is contained in:
parent
cf2be5e3bb
commit
3ffc53ba16
@ -186,7 +186,7 @@
|
||||
"`3274 <https://wg21.link/LWG3274>`__","Missing feature test macro for ``<span>``\ ","Belfast","",""
|
||||
"`3276 <https://wg21.link/LWG3276>`__","Class ``split_view::outer_iterator::value_type``\ should inherit from ``view_interface``\ ","Belfast","",""
|
||||
"`3277 <https://wg21.link/LWG3277>`__","Pre-increment on prvalues is not a requirement of ``weakly_incrementable``\ ","Belfast","",""
|
||||
"`3149 <https://wg21.link/LWG3149>`__","``DefaultConstructible``\ should require default initialization","Belfast","",""
|
||||
"`3149 <https://wg21.link/LWG3149>`__","``DefaultConstructible``\ should require default initialization","Belfast","|Complete|","13.0"
|
||||
"","","","",""
|
||||
"`1203 <https://wg21.link/LWG1203>`__","More useful rvalue stream insertion","Prague","|Complete|","12.0"
|
||||
"`2859 <https://wg21.link/LWG2859>`__","Definition of *reachable* in [ptr.launder] misses pointer arithmetic from pointer-interconvertible object","Prague","",""
|
||||
|
|
@ -167,6 +167,16 @@ template<class _Tp, class... _Args>
|
||||
concept constructible_from =
|
||||
destructible<_Tp> && _VSTD::is_constructible_v<_Tp, _Args...>;
|
||||
|
||||
// [concept.default.init]
|
||||
|
||||
template<class _Tp>
|
||||
concept __default_initializable = requires { ::new _Tp; };
|
||||
|
||||
template<class _Tp>
|
||||
concept default_initializable = constructible_from<_Tp> &&
|
||||
requires { _Tp{}; } && __default_initializable<_Tp>;
|
||||
|
||||
|
||||
#endif //_LIBCPP_STD_VER > 17 && defined(__cpp_concepts) && __cpp_concepts >= 201811L
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
@ -0,0 +1,260 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++03, c++11, c++14, c++17
|
||||
// UNSUPPORTED: libcpp-no-concepts
|
||||
|
||||
// template<class T>
|
||||
// concept default_initializable = constructible_from<T> &&
|
||||
// requires { T{}; } &&
|
||||
// is-default-initializable<T>;
|
||||
|
||||
#include <array>
|
||||
#include <concepts>
|
||||
#include <deque>
|
||||
#include <forward_list>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <queue>
|
||||
#include <set>
|
||||
#include <span>
|
||||
#include <stack>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
struct Empty {};
|
||||
|
||||
struct CtorDefaulted {
|
||||
CtorDefaulted() = default;
|
||||
};
|
||||
struct CtorDeleted {
|
||||
CtorDeleted() = delete;
|
||||
};
|
||||
struct DtorDefaulted {
|
||||
~DtorDefaulted() = default;
|
||||
};
|
||||
struct DtorDeleted {
|
||||
~DtorDeleted() = delete;
|
||||
};
|
||||
|
||||
struct Noexcept {
|
||||
~Noexcept() noexcept;
|
||||
};
|
||||
struct NoexceptTrue {
|
||||
~NoexceptTrue() noexcept(true);
|
||||
};
|
||||
struct NoexceptFalse {
|
||||
~NoexceptFalse() noexcept(false);
|
||||
};
|
||||
|
||||
struct CtorProtected {
|
||||
protected:
|
||||
CtorProtected() = default;
|
||||
};
|
||||
struct CtorPrivate {
|
||||
private:
|
||||
CtorPrivate() = default;
|
||||
};
|
||||
struct DtorProtected {
|
||||
protected:
|
||||
~DtorProtected() = default;
|
||||
};
|
||||
struct DtorPrivate {
|
||||
private:
|
||||
~DtorPrivate() = default;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct NoexceptDependant {
|
||||
~NoexceptDependant() noexcept(std::is_same_v<T, int>);
|
||||
};
|
||||
|
||||
struct CtorExplicit {
|
||||
explicit CtorExplicit() = default;
|
||||
};
|
||||
struct CtorArgument {
|
||||
CtorArgument(int) {}
|
||||
};
|
||||
struct CtorDefaultArgument {
|
||||
CtorDefaultArgument(int = 0) {}
|
||||
};
|
||||
struct CtorExplicitDefaultArgument {
|
||||
explicit CtorExplicitDefaultArgument(int = 0) {}
|
||||
};
|
||||
|
||||
struct Derived : public Empty {};
|
||||
|
||||
class Abstract {
|
||||
virtual void foo() = 0;
|
||||
};
|
||||
|
||||
class AbstractDestructor {
|
||||
virtual ~AbstractDestructor() = 0;
|
||||
};
|
||||
|
||||
class OperatorNewDeleted {
|
||||
void* operator new(std::size_t) = delete;
|
||||
void operator delete(void* ptr) = delete;
|
||||
};
|
||||
|
||||
[[maybe_unused]] auto Lambda = [](const int&, int&&, double){};
|
||||
|
||||
template<class T>
|
||||
void test_not_const()
|
||||
{
|
||||
static_assert( std::default_initializable< T>);
|
||||
static_assert(!std::default_initializable<const T>);
|
||||
static_assert( std::default_initializable< volatile T>);
|
||||
static_assert(!std::default_initializable<const volatile T>);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void test_true()
|
||||
{
|
||||
static_assert( std::default_initializable< T>);
|
||||
static_assert( std::default_initializable<const T>);
|
||||
static_assert( std::default_initializable< volatile T>);
|
||||
static_assert( std::default_initializable<const volatile T>);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void test_false()
|
||||
{
|
||||
static_assert(!std::default_initializable< T>);
|
||||
static_assert(!std::default_initializable<const T>);
|
||||
static_assert(!std::default_initializable< volatile T>);
|
||||
static_assert(!std::default_initializable<const volatile T>);
|
||||
}
|
||||
|
||||
void test()
|
||||
{
|
||||
test_not_const<bool>();
|
||||
test_not_const<char>();
|
||||
test_not_const<int>();
|
||||
test_not_const<double>();
|
||||
|
||||
test_false <void>();
|
||||
test_not_const<void*>();
|
||||
|
||||
test_not_const<int*>();
|
||||
test_false <int[]>();
|
||||
test_not_const<int[1]>();
|
||||
test_false <int&>();
|
||||
test_false <int&&>();
|
||||
|
||||
test_true <Empty>();
|
||||
|
||||
test_true <CtorDefaulted>();
|
||||
test_false <CtorDeleted>();
|
||||
test_true <DtorDefaulted>();
|
||||
test_false <DtorDeleted>();
|
||||
|
||||
test_true <Noexcept>();
|
||||
test_true <NoexceptTrue>();
|
||||
test_false <NoexceptFalse>();
|
||||
|
||||
test_false <CtorProtected>();
|
||||
test_false <CtorPrivate>();
|
||||
test_false <DtorProtected>();
|
||||
test_false <DtorPrivate>();
|
||||
|
||||
test_true <NoexceptDependant<int>>();
|
||||
test_false <NoexceptDependant<double>>();
|
||||
|
||||
test_true <CtorExplicit>();
|
||||
test_false <CtorArgument>();
|
||||
test_true <CtorDefaultArgument>();
|
||||
test_true <CtorExplicitDefaultArgument>();
|
||||
|
||||
test_true <Derived>();
|
||||
test_false <Abstract>();
|
||||
test_false <AbstractDestructor>();
|
||||
|
||||
test_true <OperatorNewDeleted>();
|
||||
|
||||
test_true <decltype(Lambda)>();
|
||||
test_not_const<void(*)(const int&)>();
|
||||
test_not_const<void(Empty::*)(const int&) >();
|
||||
test_not_const<void(Empty::*)(const int&) const >();
|
||||
test_not_const<void(Empty::*)(const int&) volatile>();
|
||||
test_not_const<void(Empty::*)(const int&) const volatile>();
|
||||
test_not_const<void(Empty::*)(const int&) &>();
|
||||
test_not_const<void(Empty::*)(const int&) &&>();
|
||||
test_not_const<void(Empty::*)(const int&) noexcept>();
|
||||
test_not_const<void(Empty::*)(const int&) noexcept(true)>();
|
||||
test_not_const<void(Empty::*)(const int&) noexcept(false)>();
|
||||
|
||||
// Sequence containers
|
||||
test_not_const<std::array< int, 0>>();
|
||||
test_not_const<std::array< int, 1>>();
|
||||
test_false <std::array<const int, 1>>();
|
||||
test_not_const<std::array< volatile int, 1>>();
|
||||
test_false <std::array<const volatile int, 1>>();
|
||||
test_true <std::deque< int>>();
|
||||
test_true <std::deque<const int>>();
|
||||
test_true <std::deque< volatile int>>();
|
||||
test_true <std::deque<const volatile int>>();
|
||||
test_true <std::forward_list<int>>();
|
||||
test_true <std::list<int>>();
|
||||
test_true <std::vector<int>>();
|
||||
|
||||
// Associative containers
|
||||
test_true <std::set<int>>();
|
||||
test_true <std::map<int, int>>();
|
||||
test_true <std::multiset<int>>();
|
||||
test_true <std::multimap<int, int>>();
|
||||
|
||||
// Unordered associative containers
|
||||
test_true <std::unordered_set<int>>();
|
||||
test_true <std::unordered_map<int, int>>();
|
||||
test_true <std::unordered_multiset<int>>();
|
||||
test_true <std::unordered_multimap<int, int>>();
|
||||
|
||||
// Container adaptors
|
||||
test_true <std::stack< int>>();
|
||||
test_true <std::stack<const int>>();
|
||||
test_true <std::stack< volatile int>>();
|
||||
test_true <std::stack<const volatile int>>();
|
||||
test_true <std::queue<int>>();
|
||||
test_true <std::priority_queue<int>>();
|
||||
|
||||
test_true <std::span< int>>();
|
||||
test_true <std::span<const int>>();
|
||||
test_true <std::span< volatile int>>();
|
||||
test_true <std::span<const volatile int>>();
|
||||
|
||||
// Strings
|
||||
test_true <std::string>();
|
||||
test_true <std::wstring>();
|
||||
test_true <std::u8string>();
|
||||
test_true <std::u16string>();
|
||||
test_true <std::u32string>();
|
||||
|
||||
// String views
|
||||
test_true <std::string_view>();
|
||||
test_true <std::wstring_view>();
|
||||
test_true <std::u8string_view>();
|
||||
test_true <std::u16string_view>();
|
||||
test_true <std::u32string_view>();
|
||||
|
||||
// Smart pointers
|
||||
test_true <std::unique_ptr<int>>();
|
||||
test_true <std::shared_ptr<int>>();
|
||||
test_true <std::weak_ptr<int>>();
|
||||
|
||||
}
|
||||
|
||||
// Required for MSVC internal test runner compatibility.
|
||||
int main(int, char**) {
|
||||
return 0;
|
||||
}
|
@ -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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++03, c++11, c++14, c++17
|
||||
// UNSUPPORTED: libcpp-no-concepts
|
||||
|
||||
// template<class T>
|
||||
// concept default_initializable = constructible_from<T> &&
|
||||
// requires { T{}; } &&
|
||||
// is-default-initializable<T>;
|
||||
|
||||
#include <concepts>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
template<class T>
|
||||
concept brace_initializable = requires { T{}; };
|
||||
|
||||
void test() {
|
||||
// LWG3149
|
||||
// Changed the concept from constructible_from<T>
|
||||
// to constructible_from<T> &&
|
||||
// requires { T{}; } && is-default-initializable <T>
|
||||
struct S0 { explicit S0() = default; };
|
||||
S0 x0;
|
||||
S0 y0{};
|
||||
static_assert( std::constructible_from<S0>);
|
||||
static_assert( brace_initializable<S0>);
|
||||
LIBCPP_STATIC_ASSERT( std::__default_initializable<S0>);
|
||||
static_assert( std::default_initializable<S0>);
|
||||
|
||||
struct S1 { S0 x; }; // Note: aggregate
|
||||
S1 x1;
|
||||
S1 y1{}; // expected-error {{chosen constructor is explicit in copy-initialization}}
|
||||
static_assert( std::constructible_from<S1>);
|
||||
static_assert(!brace_initializable<S1>);
|
||||
LIBCPP_STATIC_ASSERT( std::__default_initializable<S1>);
|
||||
static_assert(!std::default_initializable<S1>);
|
||||
|
||||
const int x2; // expected-error {{default initialization of an object of const type 'const int'}}
|
||||
const int y2{};
|
||||
|
||||
static_assert( std::constructible_from<const int>);
|
||||
static_assert( brace_initializable<const int>);
|
||||
LIBCPP_STATIC_ASSERT(!std::__default_initializable<const int>);
|
||||
static_assert(!std::default_initializable<const int>);
|
||||
|
||||
const int x3[1]; // expected-error {{default initialization of an object of const type 'const int [1]'}}
|
||||
const int y3[1]{};
|
||||
static_assert( std::constructible_from<const int[1]>);
|
||||
static_assert( brace_initializable<const int[1]>);
|
||||
LIBCPP_STATIC_ASSERT(!std::__default_initializable<const int[1]>);
|
||||
static_assert(!std::default_initializable<const int[1]>);
|
||||
|
||||
// Zero-length array extension
|
||||
const int x4[]; // expected-error {{definition of variable with array type needs an explicit size or an initializer}}
|
||||
const int y4[]{};
|
||||
static_assert(!std::constructible_from<const int[]>);
|
||||
static_assert( brace_initializable<const int[]>);
|
||||
LIBCPP_STATIC_ASSERT(!std::__default_initializable<const int[]>);
|
||||
static_assert(!std::default_initializable<const int[]>);
|
||||
}
|
||||
|
||||
int main(int, char**) {
|
||||
test();
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user