NS-3 based Named Data Networking (NDN) simulator
ndnSIM 2.5: NDN, CCN, CCNx, content centric networks
API Documentation
backports-optional.hpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2013-2018 Regents of the University of California.
4  *
5  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
6  *
7  * ndn-cxx library is free software: you can redistribute it and/or modify it under the
8  * terms of the GNU Lesser General Public License as published by the Free Software
9  * Foundation, either version 3 of the License, or (at your option) any later version.
10  *
11  * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
12  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13  * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
14  *
15  * You should have received copies of the GNU General Public License and GNU Lesser
16  * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
17  * <http://www.gnu.org/licenses/>.
18  *
19  * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
20  */
21 
42 #ifndef NDN_UTIL_BACKPORTS_OPTIONAL_HPP
43 #define NDN_UTIL_BACKPORTS_OPTIONAL_HPP
44 
45 #include "backports.hpp"
46 
47 #if (__cplusplus > 201402L) && NDN_CXX_HAS_INCLUDE(<optional>)
48 # include <optional>
49 # define NDN_CXX_HAVE_STD_OPTIONAL
50 #elif (__cplusplus > 201103L) && NDN_CXX_HAS_INCLUDE(<experimental/optional>)
51 # include <experimental/optional>
52 # if __cpp_lib_experimental_optional >= 201411
53 # define NDN_CXX_HAVE_EXPERIMENTAL_OPTIONAL
54 # endif
55 #endif
56 
57 #if defined(NDN_CXX_HAVE_STD_OPTIONAL)
58 
59 namespace ndn {
60 using std::optional;
61 using std::in_place;
62 using std::nullopt;
63 using std::bad_optional_access;
64 using std::make_optional;
65 } // namespace ndn
66 
67 #elif defined(NDN_CXX_HAVE_EXPERIMENTAL_OPTIONAL)
68 
69 namespace ndn {
70 using std::experimental::optional;
73 using std::experimental::bad_optional_access;
75 
76 template<typename T, typename... Args>
77 constexpr optional<T>
78 make_optional(Args&&... args)
79 {
80  return optional<T>(in_place, std::forward<Args>(args)...);
81 }
82 } // namespace ndn
83 
84 #else
85 
86 #include <boost/none.hpp>
87 #include <boost/optional.hpp>
88 #include <boost/utility/typed_in_place_factory.hpp>
89 
90 namespace ndn {
91 
92 template<typename T>
93 class optional;
94 
95 struct in_place_t
96 {
97 };
98 constexpr in_place_t in_place{};
99 
101 {
102 public:
103  constexpr explicit
105  {
106  }
107 };
108 constexpr nullopt_t nullopt{0};
109 
110 #if BOOST_VERSION >= 105600
111 using boost::bad_optional_access;
112 #else
113 class bad_optional_access : public std::logic_error
114 {
115 public:
117  : std::logic_error("bad optional access")
118  {
119  }
120 };
121 #endif
122 
123 template<typename T>
124 constexpr bool
125 operator==(const optional<T>& lhs, const optional<T>& rhs);
126 
127 template<typename T>
128 constexpr bool
129 operator!=(const optional<T>& lhs, const optional<T>& rhs);
130 
131 template<typename T>
132 constexpr bool
133 operator<(const optional<T>& lhs, const optional<T>& rhs);
134 
135 template<typename T>
136 constexpr bool
137 operator<=(const optional<T>& lhs, const optional<T>& rhs);
138 
139 template<typename T>
140 constexpr bool
141 operator>(const optional<T>& lhs, const optional<T>& rhs);
142 
143 template<typename T>
144 constexpr bool
145 operator>=(const optional<T>& lhs, const optional<T>& rhs);
146 
147 template<typename T>
148 class optional
149 {
150 public:
151  static_assert(!std::is_same<typename std::remove_cv<T>::type, in_place_t>::value &&
152  !std::is_same<typename std::remove_cv<T>::type, nullopt_t>::value &&
153  !std::is_reference<T>::value,
154  "Invalid instantiation of optional<T>");
155 
156  typedef T value_type;
157 
158  constexpr
159  optional() noexcept
160  {
161  }
162 
163  constexpr
164  optional(nullopt_t) noexcept
165  {
166  }
167 
168  constexpr
169  optional(const T& value)
170  : m_boostOptional(value)
171  {
172  }
173 
174  template<typename... Args>
175  constexpr explicit
176  optional(in_place_t, Args&&... args)
177  : m_boostOptional(boost::in_place<T>(std::forward<Args>(args)...))
178  {
179  }
180 
181  optional&
183  {
184  m_boostOptional = boost::none;
185  return *this;
186  }
187 
188  optional&
189  operator=(const optional& other)
190  {
191  m_boostOptional = other.m_boostOptional;
192  return *this;
193  }
194 
195  template<typename U,
196  typename = typename std::enable_if<std::is_same<typename std::decay<U>::type, T>::value>::type>
197  optional&
199  {
200  m_boostOptional = std::forward<U>(value);
201  return *this;
202  }
203 
204 public: // observers
205  constexpr const T*
206  operator->() const
207  {
208  return m_boostOptional.get_ptr();
209  }
210 
211  T*
213  {
214  return m_boostOptional.get_ptr();
215  }
216 
217  constexpr const T&
218  operator*() const
219  {
220  return m_boostOptional.get();
221  }
222 
223  T&
225  {
226  return m_boostOptional.get();
227  }
228 
229  constexpr explicit
230  operator bool() const noexcept
231  {
232  return static_cast<bool>(m_boostOptional);
233  }
234 
235  const T&
236  value() const
237  {
238  return const_cast<optional*>(this)->value();
239  }
240 
241  T&
243  {
244 #if BOOST_VERSION >= 105600
245  return m_boostOptional.value();
246 #else
247  if (!m_boostOptional) {
248  BOOST_THROW_EXCEPTION(bad_optional_access());
249  }
250  return m_boostOptional.get();
251 #endif
252  }
253 
254  template<typename U>
255  constexpr T
256  value_or(U&& default_value) const
257  {
258 #if BOOST_VERSION >= 105600
259  return m_boostOptional.value_or(default_value);
260 #else
261  return m_boostOptional.get_value_or(default_value);
262 #endif
263  }
264 
265 public: // modifiers
266  void
267  swap(optional& other)
268  {
269  boost::swap(m_boostOptional, other.m_boostOptional);
270  }
271 
272  void
273  reset() noexcept
274  {
275  m_boostOptional = boost::none;
276  }
277 
278  template<typename... Args>
279  void
280  emplace(Args&&... args)
281  {
282  m_boostOptional = boost::in_place<T>(std::forward<Args>(args)...);
283  }
284 
285 private:
286  boost::optional<T> m_boostOptional;
287 
288  friend bool operator==<T>(const optional<T>&, const optional<T>&);
289  friend bool operator!=<T>(const optional<T>&, const optional<T>&);
290  friend bool operator< <T>(const optional<T>&, const optional<T>&);
291  friend bool operator<=<T>(const optional<T>&, const optional<T>&);
292  friend bool operator> <T>(const optional<T>&, const optional<T>&);
293  friend bool operator>=<T>(const optional<T>&, const optional<T>&);
294 };
295 
296 template<typename T>
297 constexpr bool
298 operator==(const optional<T>& lhs, const optional<T>& rhs)
299 {
300  return operator==(lhs.m_boostOptional, rhs.m_boostOptional);
301 }
302 
303 template<typename T>
304 constexpr bool
305 operator!=(const optional<T>& lhs, const optional<T>& rhs)
306 {
307  return operator!=(lhs.m_boostOptional, rhs.m_boostOptional);
308 }
309 
310 template<typename T>
311 constexpr bool
312 operator<(const optional<T>& lhs, const optional<T>& rhs)
313 {
314  return operator<(lhs.m_boostOptional, rhs.m_boostOptional);
315 }
316 
317 template<typename T>
318 constexpr bool
319 operator<=(const optional<T>& lhs, const optional<T>& rhs)
320 {
321  return operator<=(lhs.m_boostOptional, rhs.m_boostOptional);
322 }
323 
324 template<typename T>
325 constexpr bool
326 operator>(const optional<T>& lhs, const optional<T>& rhs)
327 {
328  return operator>(lhs.m_boostOptional, rhs.m_boostOptional);
329 }
330 
331 template<typename T>
332 constexpr bool
333 operator>=(const optional<T>& lhs, const optional<T>& rhs)
334 {
335  return operator>=(lhs.m_boostOptional, rhs.m_boostOptional);
336 }
337 
338 template<typename T>
339 constexpr optional<typename std::decay<T>::type>
340 make_optional(T&& value)
341 {
342  return optional<typename std::decay<T>::type>(std::forward<T>(value));
343 }
344 
345 template<typename T, typename... Args>
346 constexpr optional<T>
347 make_optional(Args&&... args)
348 {
349  return optional<T>(in_place, std::forward<Args>(args)...);
350 }
351 
352 } // namespace ndn
353 
354 #endif
355 #endif // NDN_UTIL_BACKPORTS_OPTIONAL_HPP
constexpr in_place_t in_place
constexpr nullopt_t nullopt
Copyright (c) 2011-2015 Regents of the University of California.
void swap(optional &other)
optional & operator=(const optional &other)
void emplace(Args &&... args)
constexpr T value_or(U &&default_value) const
constexpr nullopt_t(int)
STL namespace.
constexpr optional(const T &value)
bool operator<=(const Delegation &lhs, const Delegation &rhs)
Definition: delegation.cpp:43
optional & operator=(nullopt_t) noexcept
bool operator!=(const Data &lhs, const Data &rhs)
Definition: data.hpp:280
constexpr optional(in_place_t, Args &&... args)
constexpr const T & operator*() const
constexpr optional() noexcept
const T & value() const
constexpr optional< typename std::decay< T >::type > make_optional(T &&value)
bool operator>(const Delegation &lhs, const Delegation &rhs)
Definition: delegation.hpp:54
constexpr optional< T > make_optional(Args &&... args)
bool operator>=(const Delegation &lhs, const Delegation &rhs)
Definition: delegation.hpp:60
bool operator==(const Data &lhs, const Data &rhs)
Definition: data.cpp:328
optional & operator=(U &&value)
void reset() noexcept
bool operator<(const Delegation &lhs, const Delegation &rhs)
Definition: delegation.cpp:36
constexpr const T * operator->() const
constexpr optional(nullopt_t) noexcept