brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.5 KiB · 9cfb5f4 Raw
100 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 O1>12// struct in_out_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::in_out_result<A, A>, std::ranges::in_out_result<int, int>>);25 26struct B {27  B(int);28};29// implicit conversion30static_assert(std::is_constructible_v<std::ranges::in_out_result<B, B>, std::ranges::in_out_result<int, int>>);31static_assert(std::is_constructible_v<std::ranges::in_out_result<B, B>, std::ranges::in_out_result<int, int>&>);32static_assert(std::is_constructible_v<std::ranges::in_out_result<B, B>, const std::ranges::in_out_result<int, int>>);33static_assert(std::is_constructible_v<std::ranges::in_out_result<B, B>, const std::ranges::in_out_result<int, int>&>);34 35struct C {36  C(int&);37};38static_assert(!std::is_constructible_v<std::ranges::in_out_result<C, C>, std::ranges::in_out_result<int, int>&>);39 40// has to be convertible via const&41static_assert(std::is_convertible_v<std::ranges::in_out_result<int, int>&, std::ranges::in_out_result<long, long>>);42static_assert(std::is_convertible_v<const std::ranges::in_out_result<int, int>&, std::ranges::in_out_result<long, long>>);43static_assert(std::is_convertible_v<std::ranges::in_out_result<int, int>&&, std::ranges::in_out_result<long, long>>);44static_assert(std::is_convertible_v<const std::ranges::in_out_result<int, int>&&, std::ranges::in_out_result<long, long>>);45 46// should be move constructible47static_assert(std::is_move_constructible_v<std::ranges::in_out_result<MoveOnly, int>>);48static_assert(std::is_move_constructible_v<std::ranges::in_out_result<int, MoveOnly>>);49 50struct NotConvertible {};51// conversions should not work if there is no conversion52static_assert(!std::is_convertible_v<std::ranges::in_out_result<NotConvertible, int>, std::ranges::in_out_result<int, NotConvertible>>);53static_assert(!std::is_convertible_v<std::ranges::in_out_result<int, NotConvertible>, std::ranges::in_out_result<NotConvertible, int>>);54 55template <class T>56struct ConvertibleFrom {57  constexpr ConvertibleFrom(T c) : content{c} {}58  T content;59};60 61constexpr bool test() {62  // Checks that conversion operations are correct.63  {64    std::ranges::in_out_result<double, int> res{10, 1};65    assert(res.in == 10);66    assert(res.out == 1);67    std::ranges::in_out_result<ConvertibleFrom<double>, ConvertibleFrom<int>> res2 = res;68    assert(res2.in.content == 10);69    assert(res2.out.content == 1);70  }71 72  // Checks that conversions are possible when one of the types is move-only.73  {74    std::ranges::in_out_result<MoveOnly, int> res{MoveOnly{}, 10};75    assert(res.in.get() == 1);76    assert(res.out == 10);77    auto res2 = std::move(res);78    assert(res.in.get() == 0);79    assert(res.out == 10);80    assert(res2.in.get() == 1);81    assert(res2.out == 10);82  }83 84  // Checks that structured bindings get the correct values.85  {86    auto [min, max] = std::ranges::in_out_result<int, int>{1, 2};87    assert(min == 1);88    assert(max == 2);89  }90 91  return true;92}93 94int main(int, char**) {95  test();96  static_assert(test());97 98  return 0;99}100