From: Jonathan Wakely Date: Thu, 24 Oct 2019 09:35:07 +0000 (+0100) Subject: Define std::uniform_random_bit_generator concept for C++20 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=bbf0495dd2b583c54d5ff591f4f1351f74d98bf9;p=gcc.git Define std::uniform_random_bit_generator concept for C++20 * include/bits/random.h (uniform_random_bit_generator): Define for C++20. * testsuite/26_numerics/random/concept.cc: New test. * testsuite/26_numerics/random/pr60037-neg.cc: Adjust dg-error line. From-SVN: r277369 --- diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 74fd23bacbf..15448962fcf 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,10 @@ +2019-10-24 Jonathan Wakely + + * include/bits/random.h (uniform_random_bit_generator): Define for + C++20. + * testsuite/26_numerics/random/concept.cc: New test. + * testsuite/26_numerics/random/pr60037-neg.cc: Adjust dg-error line. + 2019-10-23 Jonathan Wakely * include/std/functional (invoke): Add constexpr for C++20. diff --git a/libstdc++-v3/include/bits/random.h b/libstdc++-v3/include/bits/random.h index e63dbcf5a25..270097e07e6 100644 --- a/libstdc++-v3/include/bits/random.h +++ b/libstdc++-v3/include/bits/random.h @@ -33,6 +33,9 @@ #include #include +#if __cplusplus > 201703L +# include +#endif namespace std _GLIBCXX_VISIBILITY(default) { @@ -48,6 +51,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * @{ */ +#ifdef __cpp_lib_concepts + /// Requirements for a uniform random bit generator. + template + concept uniform_random_bit_generator + = invocable<_Gen&> && unsigned_integral> + && requires + { + { _Gen::min() } -> same_as>; + { _Gen::max() } -> same_as>; + }; +#endif + /** * @brief A function template for converting the output of a (integral) * uniform random number generator to a floatng point result in the range diff --git a/libstdc++-v3/testsuite/26_numerics/random/concept.cc b/libstdc++-v3/testsuite/26_numerics/random/concept.cc new file mode 100644 index 00000000000..1794ad05419 --- /dev/null +++ b/libstdc++-v3/testsuite/26_numerics/random/concept.cc @@ -0,0 +1,221 @@ +// Copyright (C) 2019 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// { dg-options "-std=gnu++2a" } +// { dg-do compile { target c++2a } } +// { dg-require-cstdint "" } + +#include + +static_assert( std::uniform_random_bit_generator ); +static_assert( std::uniform_random_bit_generator ); +static_assert( std::uniform_random_bit_generator ); + +struct G1 +{ + unsigned char operator()(); + static constexpr unsigned char min() { return 0; } + static constexpr unsigned char max() { return 10; } +}; + +static_assert( std::uniform_random_bit_generator ); + +struct G2 +{ + unsigned operator()(); + static constexpr unsigned min() { return 0; } + static constexpr unsigned max() { return -1U; } +}; + +static_assert( std::uniform_random_bit_generator ); + +struct G3 +{ + unsigned long long operator()(); + static constexpr unsigned long long min() { return 0; } + static constexpr unsigned long long max() { return -1ULL; } +}; + +static_assert( std::uniform_random_bit_generator ); + +struct G4 +{ + unsigned operator()(int = 0, int = 0); // extra params, with default args + static constexpr unsigned min(long = 0) { return 0; } + static constexpr unsigned max(void* = nullptr) { return -1U; } +}; + +static_assert( std::uniform_random_bit_generator ); + +struct G5 +{ + unsigned operator()() &; // ref-qualifier + static constexpr unsigned min() { return 0; } + static constexpr unsigned max() { return 10; } +}; + +static_assert( std::uniform_random_bit_generator ); + +struct G6 +{ + unsigned operator()() const; // cv-qualifier + static constexpr unsigned min() { return 0; } + static constexpr unsigned max() { return 10; } +}; + +static_assert( std::uniform_random_bit_generator ); + +struct G7 +{ + unsigned operator()() volatile; // cv-qualifier + static constexpr unsigned min() { return 0; } + static constexpr unsigned max() { return 10; } +}; + +static_assert( std::uniform_random_bit_generator ); + +struct G8 +{ + unsigned operator()() const volatile; // cv-qualifiers + static constexpr unsigned min() { return 0; } + static constexpr unsigned max() { return 10; } +}; + +static_assert( std::uniform_random_bit_generator ); + +struct G9 +{ + unsigned operator()() const volatile; // cv-qualifiers + static constexpr unsigned min() { return 0; } + static constexpr unsigned max() { return 10; } +}; + +static_assert( std::uniform_random_bit_generator ); + +struct G10 +{ + unsigned operator()() const volatile & noexcept; // cv/ref/noexcept + static constexpr unsigned min() noexcept { return 0; } + static constexpr unsigned max() noexcept { return 10; } +}; + +static_assert( std::uniform_random_bit_generator ); + +// Negative tests. + +static_assert( ! std::uniform_random_bit_generator ); +static_assert( ! std::uniform_random_bit_generator ); +static_assert( ! std::uniform_random_bit_generator ); + +struct N1 +{ + unsigned operator()(); + constexpr unsigned min() { return 0; } // non-static + static constexpr unsigned max() { return 1; } +}; + +static_assert( ! std::uniform_random_bit_generator ); + +struct N2 +{ + unsigned operator()(); + static constexpr unsigned min() { return 0; } + constexpr unsigned max() { return 1; } // non-static +}; + +static_assert( ! std::uniform_random_bit_generator ); + +struct N3 +{ + unsigned operator()(); + // no N3::min() + static constexpr unsigned max() { return 1; } +}; + +static_assert( ! std::uniform_random_bit_generator ); + +struct N4 +{ + unsigned operator()(); + static constexpr unsigned min() { return 0; } + // no N4::max() +}; + +static_assert( ! std::uniform_random_bit_generator ); + +struct N5 +{ + // no operator() + static constexpr unsigned min() { return 0; } + static constexpr unsigned max() { return 1; } +}; + +static_assert( ! std::uniform_random_bit_generator ); + +struct N6 +{ + int operator()(); // returns signed integral + static constexpr unsigned min() { return 0; } + static constexpr unsigned max() { return 1; } +}; + +static_assert( ! std::uniform_random_bit_generator ); + +struct N7 +{ + unsigned operator()(); + static constexpr unsigned long min() { return 0; } // different return type + static constexpr unsigned max() { return 1; } +}; + +static_assert( ! std::uniform_random_bit_generator ); + +struct N8 +{ + unsigned operator()(); + static constexpr unsigned min() { return 0; } + static constexpr unsigned long max() { return 1; } // different return type +}; + +static_assert( ! std::uniform_random_bit_generator ); + +struct N9 +{ + unsigned operator()(); + static constexpr unsigned long min() { return 0; } // different return type + static constexpr unsigned long max() { return 1; } // different return type +}; + +static_assert( ! std::uniform_random_bit_generator ); + +struct N10 +{ + unsigned operator()() &&; // ref-qualifier + static constexpr unsigned min() { return 0; } + static constexpr unsigned max() { return 1; } +}; + +static_assert( ! std::uniform_random_bit_generator ); + +struct N11 +{ + unsigned operator()() const &&; // ref-qualifier + static constexpr unsigned min() { return 0; } + static constexpr unsigned max() { return 1; } +}; + +static_assert( ! std::uniform_random_bit_generator ); diff --git a/libstdc++-v3/testsuite/26_numerics/random/pr60037-neg.cc b/libstdc++-v3/testsuite/26_numerics/random/pr60037-neg.cc index f365337e789..9f7b0cec565 100644 --- a/libstdc++-v3/testsuite/26_numerics/random/pr60037-neg.cc +++ b/libstdc++-v3/testsuite/26_numerics/random/pr60037-neg.cc @@ -10,6 +10,6 @@ std::__detail::_Adaptor aurng(urng); auto x = std::generate_canonical::digits>(urng); -// { dg-error "static assertion failed: template argument must be a floating point type" "" { target *-*-* } 156 } +// { dg-error "static assertion failed: template argument must be a floating point type" "" { target *-*-* } 171 } // { dg-error "static assertion failed: template argument must be a floating point type" "" { target *-*-* } 3320 }