[libcxx] adds concept std::uniform_random_bit_generator

Implements parts of:
    - P0898R3 Standard Library Concepts
    - P1754 Rename concepts to standard_case for C++20, while we still can

Differential Revision: https://reviews.llvm.org/D96577
This commit is contained in:
Christopher Di Bella
2021-02-17 02:52:17 +00:00
committed by Christopher Di Bella
parent 71d1f785a5
commit 9f4f6ac94b
5 changed files with 163 additions and 15 deletions

View File

@@ -228,7 +228,7 @@ concept invocable = requires(_Fn&& __fn, _Args&&... __args) {
template<class _Fn, class... _Args>
concept regular_invocable = invocable<_Fn, _Args...>;
#endif //_LIBCPP_STD_VER > 17 && defined(__cpp_concepts) && __cpp_concepts >= 201811L
#endif // _LIBCPP_STD_VER > 17 && defined(__cpp_concepts) && __cpp_concepts >= 201811L
_LIBCPP_END_NAMESPACE_STD

View File

@@ -17,6 +17,9 @@
namespace std
{
// [rand.req.urng], uniform random bit generator requirements
template<class G>
concept uniform_random_bit_generator = see below; // C++20
// Engines
@@ -1678,6 +1681,7 @@ class piecewise_linear_distribution
#include <cstddef>
#include <cstdint>
#include <cmath>
#include <concepts>
#include <type_traits>
#include <initializer_list>
#include <limits>
@@ -1697,6 +1701,20 @@ _LIBCPP_PUSH_MACROS
_LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER > 17 && defined(__cpp_concepts) && __cpp_concepts >= 201811L
// [rand.req.urng]
template<class _Gen>
concept uniform_random_bit_generator =
invocable<_Gen&> && unsigned_integral<invoke_result_t<_Gen&>> &&
requires {
{ _Gen::min() } -> same_as<invoke_result_t<_Gen&>>;
{ _Gen::max() } -> same_as<invoke_result_t<_Gen&>>;
requires bool_constant<(_Gen::min() < _Gen::max())>::value;
};
#endif // _LIBCPP_STD_VER > 17 && defined(__cpp_concepts) && __cpp_concepts >= 201811L
// __is_seed_sequence
template <class _Sseq, class _Engine>

View File

@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// UNSUPPORTED: c++03, c++11, c++14, c++17
// UNSUPPORTED: libcpp-no-concepts
// template<class T>

View File

@@ -1,13 +0,0 @@
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
int main(int, char**)
{
return 0;
}

View File

@@ -0,0 +1,143 @@
//===----------------------------------------------------------------------===//
//
// 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 uniform_random_bit_generator = // see below
#include <random>
static_assert(std::uniform_random_bit_generator<
std::linear_congruential_engine<unsigned int, 0U, 1U, 2U> >);
#ifndef _LIBCPP_HAS_NO_INT128
static_assert(std::uniform_random_bit_generator<
std::subtract_with_carry_engine<__uint128_t, 1U, 2U, 3U> >);
#endif
// Not invocable
static_assert(!std::uniform_random_bit_generator<void>);
static_assert(!std::uniform_random_bit_generator<int>);
static_assert(!std::uniform_random_bit_generator<int[10]>);
static_assert(!std::uniform_random_bit_generator<int*>);
static_assert(!std::uniform_random_bit_generator<const int*>);
static_assert(!std::uniform_random_bit_generator<volatile int*>);
static_assert(!std::uniform_random_bit_generator<const volatile int*>);
static_assert(!std::uniform_random_bit_generator<int&>);
static_assert(!std::uniform_random_bit_generator<const int&>);
static_assert(!std::uniform_random_bit_generator<volatile int&>);
static_assert(!std::uniform_random_bit_generator<const volatile int&>);
static_assert(!std::uniform_random_bit_generator<int&&>);
static_assert(!std::uniform_random_bit_generator<const int&&>);
static_assert(!std::uniform_random_bit_generator<volatile int&&>);
static_assert(!std::uniform_random_bit_generator<const volatile int&&>);
struct Empty {};
static_assert(!std::uniform_random_bit_generator<Empty>);
namespace WrongReturnType {
using FunctionPointer = void (*)();
static_assert(!std::uniform_random_bit_generator<FunctionPointer>);
using FunctionReference = int (&)();
static_assert(!std::uniform_random_bit_generator<FunctionReference>);
struct FunctionObject {
unsigned long* operator()();
};
static_assert(!std::uniform_random_bit_generator<FunctionObject>);
static_assert(!std::uniform_random_bit_generator<unsigned int Empty::*>);
static_assert(!std::uniform_random_bit_generator<unsigned short (Empty::*)()>);
} // namespace WrongReturnType
namespace NoMinOrMax {
using FunctionPointer = unsigned int (*)();
static_assert(!std::uniform_random_bit_generator<FunctionPointer>);
using FunctionReference = unsigned long long (&)();
static_assert(!std::uniform_random_bit_generator<FunctionReference>);
struct FunctionObject {
unsigned char operator()();
};
static_assert(!std::uniform_random_bit_generator<FunctionObject>);
} // namespace NoMinOrMax
namespace OnlyMinIsRight {
struct NoMax {
unsigned char operator()();
static unsigned char min();
};
static_assert(!std::uniform_random_bit_generator<NoMax>);
struct MaxHasWrongReturnType {
unsigned char operator()();
static unsigned char min();
static unsigned int max();
};
static_assert(!std::uniform_random_bit_generator<MaxHasWrongReturnType>);
} // namespace OnlyMinIsRight
namespace OnlyMaxIsRight {
struct NoMin {
unsigned char operator()();
static unsigned char max();
};
static_assert(!std::uniform_random_bit_generator<NoMin>);
struct MinHasWrongReturnType {
unsigned char operator()();
static unsigned int min();
static unsigned char max();
};
static_assert(!std::uniform_random_bit_generator<MinHasWrongReturnType>);
} // namespace OnlyMaxIsRight
namespace MinNotLessMax {
struct NotConstexpr {
unsigned char operator()();
static unsigned char min();
static unsigned char max();
};
static_assert(!std::uniform_random_bit_generator<NotConstexpr>);
struct MinEqualsMax {
unsigned char operator()();
static constexpr unsigned char min() { return 0; }
static constexpr unsigned char max() { return 0; }
};
static_assert(!std::uniform_random_bit_generator<MinEqualsMax>);
struct MaxLessThanMin {
unsigned char operator()();
static constexpr unsigned char min() { return 1; }
static constexpr unsigned char max() { return 0; }
};
static_assert(!std::uniform_random_bit_generator<MaxLessThanMin>);
} // namespace MinNotLessMax
struct Works {
unsigned char operator()();
static constexpr unsigned char min() { return 0; }
static constexpr unsigned char max() { return 1; }
};
static_assert(std::uniform_random_bit_generator<Works>);
int main(int, char**) { return 0; }