139 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// owning_view() requires default_initializable<R> = default;12// constexpr owning_view(R&& t);13 14#include <ranges>15 16#include <cassert>17#include <concepts>18#include <type_traits>19#include <utility>20 21#include "test_macros.h"22 23struct DefaultConstructible {24 int i;25 constexpr explicit DefaultConstructible(int j = 42) : i(j) {}26 int *begin() const;27 int *end() const;28};29 30struct NotDefaultConstructible {31 int i;32 constexpr explicit NotDefaultConstructible(int j) : i(j) {}33 int *begin() const;34 int *end() const;35};36 37struct MoveChecker {38 int i;39 constexpr explicit MoveChecker(int j) : i(j) {}40 constexpr MoveChecker(MoveChecker&& v) : i(std::exchange(v.i, -1)) {}41 MoveChecker& operator=(MoveChecker&&);42 int *begin() const;43 int *end() const;44};45 46struct NoexceptChecker {47 int *begin() const;48 int *end() const;49};50 51constexpr bool test()52{53 {54 using OwningView = std::ranges::owning_view<DefaultConstructible>;55 static_assert(std::is_constructible_v<OwningView>);56 static_assert(std::default_initializable<OwningView>);57 static_assert(std::movable<OwningView>);58 static_assert(std::is_trivially_move_constructible_v<OwningView>);59 static_assert(std::is_trivially_move_assignable_v<OwningView>);60 static_assert(!std::is_copy_constructible_v<OwningView>);61 static_assert(!std::is_copy_assignable_v<OwningView>);62 static_assert(!std::is_constructible_v<OwningView, int>);63 static_assert(!std::is_constructible_v<OwningView, DefaultConstructible&>);64 static_assert(std::is_constructible_v<OwningView, DefaultConstructible&&>);65 static_assert(!std::is_convertible_v<int, OwningView>);66 static_assert(std::is_convertible_v<DefaultConstructible&&, OwningView>);67 {68 OwningView ov;69 assert(ov.base().i == 42);70 }71 {72 OwningView ov = OwningView(DefaultConstructible(1));73 assert(ov.base().i == 1);74 }75 }76 {77 using OwningView = std::ranges::owning_view<NotDefaultConstructible>;78 static_assert(!std::is_constructible_v<OwningView>);79 static_assert(!std::default_initializable<OwningView>);80 static_assert(std::movable<OwningView>);81 static_assert(std::is_trivially_move_constructible_v<OwningView>);82 static_assert(std::is_trivially_move_assignable_v<OwningView>);83 static_assert(!std::is_copy_constructible_v<OwningView>);84 static_assert(!std::is_copy_assignable_v<OwningView>);85 static_assert(!std::is_constructible_v<OwningView, int>);86 static_assert(!std::is_constructible_v<OwningView, NotDefaultConstructible&>);87 static_assert(std::is_constructible_v<OwningView, NotDefaultConstructible&&>);88 static_assert(!std::is_convertible_v<int, OwningView>);89 static_assert(std::is_convertible_v<NotDefaultConstructible&&, OwningView>);90 {91 OwningView ov = OwningView(NotDefaultConstructible(1));92 assert(ov.base().i == 1);93 }94 }95 {96 using OwningView = std::ranges::owning_view<MoveChecker>;97 static_assert(!std::is_constructible_v<OwningView>);98 static_assert(!std::default_initializable<OwningView>);99 static_assert(std::movable<OwningView>);100 static_assert(!std::is_trivially_move_constructible_v<OwningView>);101 static_assert(!std::is_trivially_move_assignable_v<OwningView>);102 static_assert(!std::is_copy_constructible_v<OwningView>);103 static_assert(!std::is_copy_assignable_v<OwningView>);104 static_assert(!std::is_constructible_v<OwningView, int>);105 static_assert(!std::is_constructible_v<OwningView, MoveChecker&>);106 static_assert(std::is_constructible_v<OwningView, MoveChecker&&>);107 static_assert(!std::is_convertible_v<int, OwningView>);108 static_assert(std::is_convertible_v<MoveChecker&&, OwningView>);109 {110 // Check that the constructor does indeed move from the target object.111 auto m = MoveChecker(42);112 OwningView ov = OwningView(std::move(m));113 assert(ov.base().i == 42);114 assert(m.i == -1);115 }116 }117 {118 // Check that the defaulted constructors are (not) noexcept when appropriate.119 120 static_assert( std::is_nothrow_constructible_v<NoexceptChecker>); // therefore,121 static_assert( std::is_nothrow_constructible_v<std::ranges::owning_view<NoexceptChecker>>);122 static_assert(!std::is_nothrow_constructible_v<DefaultConstructible>); // therefore,123 static_assert(!std::is_nothrow_constructible_v<std::ranges::owning_view<DefaultConstructible>>);124 125 static_assert( std::is_nothrow_move_constructible_v<NoexceptChecker>); // therefore,126 static_assert( std::is_nothrow_move_constructible_v<std::ranges::owning_view<NoexceptChecker>>);127 static_assert(!std::is_nothrow_move_constructible_v<MoveChecker>); // therefore,128 static_assert(!std::is_nothrow_move_constructible_v<std::ranges::owning_view<MoveChecker>>);129 }130 return true;131}132 133int main(int, char**) {134 test();135 static_assert(test());136 137 return 0;138}139