101 lines · cpp
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9// UNSUPPORTED: c++03, c++11, c++14, c++1710 11// template <class I1, class I2>12// struct min_max_result;13 14#include <algorithm>15#include <cassert>16#include <type_traits>17 18#include "MoveOnly.h"19 20struct A {21 explicit A(int);22};23// no implicit conversion24static_assert(!std::is_constructible_v<std::ranges::min_max_result<A>, std::ranges::min_max_result<int>>);25 26struct B {27 B(int);28};29// implicit conversion30static_assert(std::is_constructible_v<std::ranges::min_max_result<B>, std::ranges::min_max_result<int>>);31static_assert(std::is_constructible_v<std::ranges::min_max_result<B>, std::ranges::min_max_result<int>&>);32static_assert(std::is_constructible_v<std::ranges::min_max_result<B>, const std::ranges::min_max_result<int>>);33static_assert(std::is_constructible_v<std::ranges::min_max_result<B>, const std::ranges::min_max_result<int>&>);34 35struct C {36 C(int&);37};38static_assert(!std::is_constructible_v<std::ranges::min_max_result<C>, std::ranges::min_max_result<int>&>);39 40// has to be convertible via const&41static_assert(std::is_convertible_v<std::ranges::min_max_result<int>&, std::ranges::min_max_result<long>>);42static_assert(std::is_convertible_v<const std::ranges::min_max_result<int>&, std::ranges::min_max_result<long>>);43static_assert(std::is_convertible_v<std::ranges::min_max_result<int>&&, std::ranges::min_max_result<long>>);44static_assert(std::is_convertible_v<const std::ranges::min_max_result<int>&&, std::ranges::min_max_result<long>>);45 46// should be move constructible47static_assert(std::is_move_constructible_v<std::ranges::min_max_result<MoveOnly>>);48 49// should not be copy constructible50static_assert(!std::is_copy_constructible_v<std::ranges::min_max_result<MoveOnly>>);51 52struct NotConvertible {};53// conversions should not work if there is no conversion54static_assert(!std::is_convertible_v<std::ranges::min_max_result<NotConvertible>, std::ranges::min_max_result<int>>);55 56template <class T>57struct ConvertibleFrom {58 constexpr ConvertibleFrom(T c) : content{c} {}59 T content;60};61 62constexpr bool test() {63 // Checks that conversion operations are correct.64 {65 std::ranges::min_max_result<double> res{10, 1};66 assert(res.min == 10);67 assert(res.max == 1);68 std::ranges::min_max_result<ConvertibleFrom<int>> res2 = res;69 assert(res2.min.content == 10);70 assert(res2.max.content == 1);71 }72 73 // Checks that conversions are possible when one of the types is move-only.74 {75 std::ranges::min_max_result<MoveOnly> res{MoveOnly{}, MoveOnly{}};76 assert(res.min.get() == 1);77 assert(res.max.get() == 1);78 auto res2 = std::move(res);79 assert(res.min.get() == 0);80 assert(res.max.get() == 0);81 assert(res2.min.get() == 1);82 assert(res2.max.get() == 1);83 }84 85 // Checks that structured bindings get the correct values.86 {87 auto [min, max] = std::ranges::min_max_result<int>{1, 2};88 assert(min == 1);89 assert(max == 2);90 }91 92 return true;93}94 95int main(int, char**) {96 test();97 static_assert(test());98 99 return 0;100}101