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 
16 namespace Dune {
17 
32 template <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 
41 public:
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,
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,
82  disableCopyMove<CopyableOptional, Args...> = 0,
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() 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.
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
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
Utilities for type computations, constraining overloads, ...
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (May 5, 22:29, 2024)