Dune Core Modules (unstable)

copyableoptional.hh
1// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2// vi: set et ts=4 sw=2 sts=2:
3// SPDX-FileCopyrightInfo: Copyright © DUNE Project contributors, see file LICENSE.md in module root
4// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
5#ifndef DUNE_COMMON_COPYABLE_OPTIONAL_HH
6#define DUNE_COMMON_COPYABLE_OPTIONAL_HH
7
8#include <cassert>
9#include <iostream>
10#include <memory>
11#include <optional>
12#include <type_traits>
13
15
16namespace Dune {
17
32template <class Type>
34 : public std::optional<Type>
35{
36 static_assert(std::is_copy_constructible_v<Type>);
37 static_assert(std::is_object_v<Type>);
38
39 using Base = std::optional<Type>;
40
41public:
42
47 template <class T = Type,
48 std::enable_if_t<std::is_default_constructible_v<T>, int> = 0>
49 constexpr CopyableOptional ()
50 noexcept(std::is_nothrow_default_constructible_v<T>)
51 : Base{std::in_place}
52 {}
53
58 template <class T = Type,
59 disableCopyMove<CopyableOptional,T> = 0,
60 std::enable_if_t<std::is_constructible_v<Type,T&&>, int> = 0,
61 std::enable_if_t<std::is_convertible_v<T&&,Type>, int> = 0>
62 constexpr CopyableOptional (T&& value)
63 noexcept(std::is_nothrow_constructible_v<Type,T&&>)
64 : Base{std::in_place, std::forward<T>(value)}
65 {}
66
71 template <class T = Type,
72 disableCopyMove<CopyableOptional,T> = 0,
73 std::enable_if_t<std::is_constructible_v<Type,T&&>, int> = 0,
74 std::enable_if_t<not std::is_convertible_v<T&&,Type>, int> = 0>
75 explicit constexpr CopyableOptional (T&& value)
76 noexcept(std::is_nothrow_constructible_v<Type,T&&>)
77 : Base{std::in_place, std::forward<T>(value)}
78 {}
79
81 template <class... Args,
83 std::enable_if_t<(sizeof...(Args) > 1), int> = 0,
84 std::enable_if_t<std::is_constructible_v<Type,Args&&...>, int> = 0>
85 constexpr CopyableOptional (Args&&... args)
86 noexcept(std::is_nothrow_constructible_v<Type,Args&&...>)
87 : Base{std::in_place, std::forward<Args>(args)...}
88 {}
89
91 constexpr CopyableOptional (const CopyableOptional&) = default;
92
94 constexpr CopyableOptional (CopyableOptional&&) = default;
95
97 ~CopyableOptional () = default;
98
101 noexcept(std::is_nothrow_copy_assignable_v<Type> ||
102 (!std::is_copy_assignable_v<Type> && std::is_nothrow_copy_constructible_v<Type>))
103 {
104 if constexpr(std::is_copy_assignable_v<Type>)
105 Base::operator=(that);
106 else {
107 // no self-assignment
108 if (this != std::addressof(that)) {
109 if (that)
110 Base::emplace(*that);
111 else
112 Base::reset();
113 }
114 }
115 return *this;
116 }
117
119 template <class T = Type,
120 std::enable_if_t<std::is_move_constructible_v<T>, int> = 0>
122 noexcept(std::is_nothrow_move_assignable_v<Type> ||
123 (!std::is_move_assignable_v<Type> && std::is_nothrow_move_constructible_v<Type>))
124 {
125 if constexpr(std::is_move_assignable_v<Type>)
126 Base::operator=(std::move(that));
127 else {
128 // no self-assignment
129 if (this != std::addressof(that)) {
130 if (that)
131 Base::emplace(std::move(*that));
132 else
133 Base::reset();
134 }
135 }
136 return *this;
137 }
138
140 template <class T = Type,
141 std::enable_if_t<not std::is_same_v<std::decay_t<T>, CopyableOptional>, int> = 0,
142 std::enable_if_t<(std::is_assignable_v<Type&,T> || std::is_constructible_v<Type,T>), int> = 0>
143 constexpr CopyableOptional& operator= (T&& value)
144 noexcept(std::is_nothrow_assignable_v<Type&,T> ||
145 (!std::is_assignable_v<Type&,T> && std::is_nothrow_constructible_v<Type,T>))
146 {
147 if constexpr(std::is_assignable_v<Type&,T>)
148 Base::operator=(std::forward<T>(value));
149 else
150 Base::emplace(std::forward<T>(value));
151 return *this;
152 }
153};
154
155} // end namespace Dune
156
157#endif // DUNE_COMMON_COPYABLE_OPTIONAL_HH
A copyable type wrapper that provides copy/move assignment operations for types that are only copy/mo...
Definition: copyableoptional.hh:35
constexpr CopyableOptional(CopyableOptional &&)=default
Move construct the contained value.
constexpr CopyableOptional(T &&value) noexcept(std::is_nothrow_constructible_v< Type, T && >)
Construct the internal data from perfect forwarding of the passed arguments. Participates in overload...
Definition: copyableoptional.hh:62
constexpr CopyableOptional & operator=(const CopyableOptional &that) noexcept(std::is_nothrow_copy_assignable_v< Type >||(!std::is_copy_assignable_v< Type > &&std::is_nothrow_copy_constructible_v< Type >))
Copy assignment in terms of copy constructor.
Definition: copyableoptional.hh:100
constexpr CopyableOptional() noexcept(std::is_nothrow_default_constructible_v< T >)
Implementation of a default constructor, if the Type is itself default constructible....
Definition: copyableoptional.hh:49
constexpr CopyableOptional(const CopyableOptional &)=default
Copy construct the contained value.
constexpr CopyableOptional(Args &&... args) noexcept(std::is_nothrow_constructible_v< Type, Args &&... >)
Construct the internal data from perfect forwarding of the passed arguments.
Definition: copyableoptional.hh:85
~CopyableOptional()=default
Default destructor.
std::enable_if_t< not Impl::disableCopyMoveHelper< This, T... >::value, int > disableCopyMove
Helper to disable constructor as copy and move constructor.
Definition: typeutilities.hh:45
Dune namespace.
Definition: alignedallocator.hh:13
STL namespace.
Utilities for type computations, constraining overloads, ...
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Nov 24, 23:30, 2024)