aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libstdc++-v3/include/bits/chrono.h19
-rw-r--r--libstdc++-v3/include/std/ratio53
-rw-r--r--libstdc++-v3/testsuite/20_util/duration/requirements/typedefs_neg1.cc2
-rw-r--r--libstdc++-v3/testsuite/20_util/duration/requirements/typedefs_neg2.cc2
-rw-r--r--libstdc++-v3/testsuite/20_util/ratio/requirements/type_constraints.cc34
5 files changed, 87 insertions, 23 deletions
diff --git a/libstdc++-v3/include/bits/chrono.h b/libstdc++-v3/include/bits/chrono.h
index 81b92d7..e949076 100644
--- a/libstdc++-v3/include/bits/chrono.h
+++ b/libstdc++-v3/include/bits/chrono.h
@@ -505,26 +505,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ return numeric_limits<_Rep>::lowest(); }
};
- /// @cond undocumented
-
- template<typename _Tp>
- struct __is_ratio
- : std::false_type
- { };
-
- template<intmax_t _Num, intmax_t _Den>
- struct __is_ratio<ratio<_Num, _Den>>
- : std::true_type
- { };
-
- /// @endcond
-
template<typename _Rep, typename _Period>
class duration
{
- static_assert(!__is_duration<_Rep>::value, "rep cannot be a duration");
+ static_assert(!__is_duration<_Rep>::value,
+ "rep cannot be a std::chrono::duration");
static_assert(__is_ratio<_Period>::value,
- "period must be a specialization of ratio");
+ "period must be a specialization of std::ratio");
static_assert(_Period::num > 0, "period must be positive");
template<typename _Rep2>
diff --git a/libstdc++-v3/include/std/ratio b/libstdc++-v3/include/std/ratio
index 183f1ae..1d285bf 100644
--- a/libstdc++-v3/include/std/ratio
+++ b/libstdc++-v3/include/std/ratio
@@ -289,9 +289,43 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
/// @cond undocumented
+ template<typename _Tp>
+ struct __is_ratio
+ : std::false_type
+ { };
+
+ template<intmax_t _Num, intmax_t _Den>
+ struct __is_ratio<ratio<_Num, _Den>>
+ : std::true_type
+ { };
+
+#if __cpp_variable_templates
+ template<typename _Tp>
+ constexpr bool __is_ratio_v = false;
+ template<intmax_t _Num, intmax_t _Den>
+ constexpr bool __is_ratio_v<ratio<_Num, _Den>> = true;
+#endif
+
+ template<typename _R1, typename _R2>
+ constexpr bool
+ __are_both_ratios() noexcept
+ {
+#if __cpp_variable_templates && __cpp_if_constexpr
+ if constexpr (__is_ratio_v<_R1>)
+ if constexpr (__is_ratio_v<_R2>)
+ return true;
+ return false;
+#else
+ return __and_<__is_ratio<_R1>, __is_ratio<_R2>>::value;
+#endif
+ }
+
template<typename _R1, typename _R2>
struct __ratio_multiply
{
+ static_assert(std::__are_both_ratios<_R1, _R2>(),
+ "both template arguments must be a std::ratio");
+
private:
static const intmax_t __gcd1 =
__static_gcd<_R1::num, _R2::den>::value;
@@ -356,7 +390,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _R1, typename _R2>
struct ratio_equal
: integral_constant<bool, _R1::num == _R2::num && _R1::den == _R2::den>
- { };
+ {
+ static_assert(std::__are_both_ratios<_R1, _R2>(),
+ "both template arguments must be a std::ratio");
+ };
/// ratio_not_equal
template<typename _R1, typename _R2>
@@ -402,7 +439,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _R1, typename _R2>
struct ratio_less
: __ratio_less_impl<_R1, _R2>::type
- { };
+ {
+ static_assert(std::__are_both_ratios<_R1, _R2>(),
+ "both template arguments must be a std::ratio");
+ };
/// ratio_less_equal
template<typename _R1, typename _R2>
@@ -430,13 +470,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template <typename _R1, typename _R2>
inline constexpr bool ratio_less_v = ratio_less<_R1, _R2>::value;
template <typename _R1, typename _R2>
- inline constexpr bool ratio_less_equal_v =
- ratio_less_equal<_R1, _R2>::value;
+ inline constexpr bool ratio_less_equal_v
+ = ratio_less_equal<_R1, _R2>::value;
template <typename _R1, typename _R2>
inline constexpr bool ratio_greater_v = ratio_greater<_R1, _R2>::value;
template <typename _R1, typename _R2>
inline constexpr bool ratio_greater_equal_v
- = ratio_greater_equal<_R1, _R2>::value;
+ = ratio_greater_equal<_R1, _R2>::value;
#endif // C++17
/// @cond undocumented
@@ -513,6 +553,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _R1, typename _R2>
struct __ratio_add
{
+ static_assert(std::__are_both_ratios<_R1, _R2>(),
+ "both template arguments must be a std::ratio");
+
typedef typename __ratio_add_impl<_R1, _R2>::type type;
static constexpr intmax_t num = type::num;
static constexpr intmax_t den = type::den;
diff --git a/libstdc++-v3/testsuite/20_util/duration/requirements/typedefs_neg1.cc b/libstdc++-v3/testsuite/20_util/duration/requirements/typedefs_neg1.cc
index 49c9fe7..1a1188b 100644
--- a/libstdc++-v3/testsuite/20_util/duration/requirements/typedefs_neg1.cc
+++ b/libstdc++-v3/testsuite/20_util/duration/requirements/typedefs_neg1.cc
@@ -29,4 +29,4 @@ void test01()
test_type d; // { dg-error "required from here" }
}
-// { dg-error "rep cannot be a duration" "" { target *-*-* } 0 }
+// { dg-error "rep cannot be a std::chrono::duration" "" { target *-*-* } 0 }
diff --git a/libstdc++-v3/testsuite/20_util/duration/requirements/typedefs_neg2.cc b/libstdc++-v3/testsuite/20_util/duration/requirements/typedefs_neg2.cc
index 23c5d47..cbdb7af 100644
--- a/libstdc++-v3/testsuite/20_util/duration/requirements/typedefs_neg2.cc
+++ b/libstdc++-v3/testsuite/20_util/duration/requirements/typedefs_neg2.cc
@@ -30,7 +30,7 @@ void test01()
test_type d; // { dg-error "required from here" }
}
-// { dg-error "must be a specialization of ratio" "" { target *-*-* } 0 }
+// { dg-error "must be a specialization of std::ratio" "" { target *-*-* } 0 }
// { dg-prune-output "'num' is not a member of 'int'" }
// { dg-prune-output "'den' is not a member of 'int'" }
// { dg-prune-output "'int' is not a class, struct, or union type" }
diff --git a/libstdc++-v3/testsuite/20_util/ratio/requirements/type_constraints.cc b/libstdc++-v3/testsuite/20_util/ratio/requirements/type_constraints.cc
new file mode 100644
index 0000000..ebf09bc
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/ratio/requirements/type_constraints.cc
@@ -0,0 +1,34 @@
+// { dg-do compile { target c++11 } }
+
+// C++11 20.10.1 [ratio.general]
+// if the template argument types R1 and R2 are not specializations of the
+// ratio template, the program is ill-formed.
+
+#include <ratio>
+
+using namespace std;
+
+// A type that looks like std::ratio but isn't.
+template<int> struct Ratty { static constexpr int num = 1, den = 1; };
+
+using T1 = ratio_add<Ratty<1>, Ratty<1>>::type; // { dg-error "here" }
+using T2 = ratio_subtract<Ratty<3>, Ratty<3>>::type; // { dg-error "here" }
+using T3 = ratio_multiply<Ratty<3>, Ratty<3>>::type; // { dg-error "here" }
+using T4 = ratio_divide<Ratty<4>, Ratty<4>>::type; // { dg-error "here" }
+using T5 = ratio_equal<Ratty<5>, Ratty<5>>::type; // { dg-error "here" }
+using T6 = ratio_not_equal<Ratty<6>, Ratty<6>>::type; // { dg-error "here" }
+using T7 = ratio_less<Ratty<7>, Ratty<7>>::type; // { dg-error "here" }
+using T8 = ratio_less_equal<Ratty<8>, Ratty<8>>::type; // { dg-error "here" }
+using T9 = ratio_greater<Ratty<9>, Ratty<9>>::type; // { dg-error "here" }
+using T10 = ratio_greater_equal<Ratty<10>, Ratty<10>>::type; // { dg-error "here" }
+
+#if __cplusplus >= 201703L
+bool B11 = ratio_equal_v<Ratty<11>, Ratty<11>>; // { dg-error "here" "" { target c++17 } }
+bool B12 = ratio_not_equal_v<Ratty<12>, Ratty<12>>; // { dg-error "here" "" { target c++17 } }
+bool B13 = ratio_less_v<Ratty<13>, Ratty<13>>; // { dg-error "here" "" { target c++17 } }
+bool B14 = ratio_less_equal_v<Ratty<14>, Ratty<14>>; // { dg-error "here" "" { target c++17 } }
+bool B15 = ratio_greater_v<Ratty<15>, Ratty<15>>; // { dg-error "here" "" { target c++17 } }
+bool B16 = ratio_greater_equal_v<Ratty<16>, Ratty<16>>; // { dg-error "here" "" { target c++17 } }
+#endif
+
+// { dg-error "static assertion failed" "" { target *-*-* } 0 }