brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.7 KiB · 4395380 Raw
103 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 in_fun_result;13 14#include <algorithm>15#include <cassert>16#include <type_traits>17#include <utility>18 19#include "MoveOnly.h"20 21struct A {22  explicit A(int);23};24// no implicit conversion25static_assert(!std::is_constructible_v<std::ranges::in_fun_result<A, A>, std::ranges::in_fun_result<int, int>>);26 27struct B {28  B(int);29};30// implicit conversion31static_assert(std::is_constructible_v<std::ranges::in_fun_result<B, B>, std::ranges::in_fun_result<int, int>>);32static_assert(std::is_constructible_v<std::ranges::in_fun_result<B, B>, std::ranges::in_fun_result<int, int>&>);33static_assert(std::is_constructible_v<std::ranges::in_fun_result<B, B>, const std::ranges::in_fun_result<int, int>>);34static_assert(std::is_constructible_v<std::ranges::in_fun_result<B, B>, const std::ranges::in_fun_result<int, int>&>);35 36struct C {37  C(int&);38};39static_assert(!std::is_constructible_v<std::ranges::in_fun_result<C, C>, std::ranges::in_fun_result<int, int>&>);40 41// has to be convertible via const&42static_assert(std::is_convertible_v<std::ranges::in_fun_result<int, int>&, std::ranges::in_fun_result<long, long>>);43static_assert(std::is_convertible_v<const std::ranges::in_fun_result<int, int>&, std::ranges::in_fun_result<long, long>>);44static_assert(std::is_convertible_v<std::ranges::in_fun_result<int, int>&&, std::ranges::in_fun_result<long, long>>);45static_assert(std::is_convertible_v<const std::ranges::in_fun_result<int, int>&&, std::ranges::in_fun_result<long, long>>);46 47// should be move constructible48static_assert(std::is_move_constructible_v<std::ranges::in_fun_result<MoveOnly, int>>);49static_assert(std::is_move_constructible_v<std::ranges::in_fun_result<int, MoveOnly>>);50 51// should not be copy constructible with move-only type52static_assert(!std::is_copy_constructible_v<std::ranges::in_fun_result<MoveOnly, int>>);53static_assert(!std::is_copy_constructible_v<std::ranges::in_fun_result<int, MoveOnly>>);54 55struct NotConvertible {};56// conversions should not work if there is no conversion57static_assert(!std::is_convertible_v<std::ranges::in_fun_result<NotConvertible, int>, std::ranges::in_fun_result<int, int>>);58static_assert(!std::is_convertible_v<std::ranges::in_fun_result<int, NotConvertible>, std::ranges::in_fun_result<int, int>>);59 60template <class T>61struct ConvertibleFrom {62  constexpr ConvertibleFrom(T c) : content{c} {}63  T content;64};65 66constexpr bool test() {67  // Checks that conversion operations are correct.68  {69    std::ranges::in_fun_result<int, double> res{10, 0.};70    assert(res.in == 10);71    assert(res.fun == 0.);72    std::ranges::in_fun_result<ConvertibleFrom<int>, ConvertibleFrom<double>> res2 = res;73    assert(res2.in.content == 10);74    assert(res2.fun.content == 0.);75  }76 77  // Checks that conversions are possible when one of the types is move-only.78  {79    std::ranges::in_fun_result<MoveOnly, int> res{MoveOnly{}, 2};80    assert(res.in.get() == 1);81    assert(res.fun == 2);82    auto res2 = static_cast<std::ranges::in_fun_result<MoveOnly, int>>(std::move(res));83    assert(res.in.get() == 0);84    assert(res2.in.get() == 1);85    assert(res2.fun == 2);86  }87 88  // Checks that structured bindings get the correct values.89  {90    auto [in, fun] = std::ranges::in_fun_result<int, int>{1, 2};91    assert(in == 1);92    assert(fun == 2);93  }94  return true;95}96 97int main(int, char**) {98  test();99  static_assert(test());100 101  return 0;102}103