mod_servlet
C++Servlets
 All Classes Files Functions Variables Typedefs Macros Pages
optional.h
Go to the documentation of this file.
1 /*
2 Copyright (c) 2016 Alexei Novakov
3 https://github.com/novalexei
4 
5 Distributed under the Boost Software License, Version 1.0.
6 http://boost.org/LICENSE_1_0.txt
7 */
8 #ifndef SERVLET_OPTIONAL_H
9 #define SERVLET_OPTIONAL_H
10 
16 #include <utility>
17 #include <type_traits>
18 
19 #include <servlet/lib/exception.h>
20 
21 namespace servlet
22 {
23 
32 template<typename T>
34 {
35 public:
39  typedef T value_type;
43  typedef T *pointer;
47  typedef const T *const_pointer;
48 
55  constexpr optional_ptr() {}
63  constexpr optional_ptr(T* ptr, bool owner = false) : _ptr{ptr}, _owner{owner} {}
64 
69  constexpr optional_ptr(const optional_ptr &other) = delete;
74  constexpr optional_ptr(optional_ptr &&other) : _ptr{other._ptr}, _owner{other._owner}
75  { other._ptr = nullptr; other._owner = false; }
76 
83  ~optional_ptr() noexcept { if (_owner) delete _ptr; }
84 
92  constexpr void clear()
93  {
94  if (_owner) delete _ptr;
95  _ptr = nullptr; _owner = false;
96  }
97 
101  constexpr optional_ptr& operator=(const optional_ptr &other) = delete;
111  constexpr optional_ptr& operator=(optional_ptr &&other) noexcept
112  {
113  if (_owner) delete _ptr;
114  _ptr = other._ptr; _owner = other._owner;
115  other._ptr = nullptr; other._owner = false;
116  return *this;
117  }
118 
129  constexpr optional_ptr& assign(T* ptr, bool owner = false)
130  {
131  if (_owner) delete _ptr;
132  _ptr = ptr; _owner = owner;
133  return *this;
134  }
135 
142  constexpr explicit operator bool() const noexcept { return _ptr != nullptr; }
148  constexpr bool has_value() const noexcept { return _ptr != nullptr; }
154  constexpr bool is_owner() const noexcept { return _owner; }
155 
161  constexpr T *operator->() { return _ptr ? _ptr : throw null_pointer_exception{"pointer is NULL"}; }
167  constexpr const T *operator->() const
168  { return _ptr ? _ptr : throw null_pointer_exception{"pointer is NULL"}; }
169 
176  constexpr T& operator*() & { if (!_ptr) throw null_pointer_exception{"pointer is NULL"}; return *_ptr; }
183  constexpr const T& operator*() const& { if (!_ptr) throw null_pointer_exception{"pointer is NULL"}; return *_ptr; }
184 
189  constexpr void swap(optional_ptr &other) noexcept
190  {
191  T *tmp_ptr = _ptr;
192  _ptr = other._ptr;
193  other._ptr = tmp_ptr;
194  bool tmp_owner = _owner;
195  _owner = other._owner;
196  other._owner = tmp_owner;
197  }
203  constexpr void reset() noexcept { clear(); }
204 
205 private:
206  bool _owner = false;
207  T* _ptr = nullptr;
208 };
209 
220 template<typename T>
222 {
223  T *_ptr = nullptr;
224 public:
228  typedef T value_type;
232  typedef T &reference;
236  typedef const T &const_reference;
237 
243  constexpr optional_ref() noexcept {}
248  constexpr optional_ref(T &obj) noexcept : _ptr{&obj} {}
249 
254  constexpr optional_ref(const optional_ref &other) noexcept : _ptr{other._ptr} {}
259  constexpr optional_ref(optional_ref&& other) noexcept : _ptr{other._ptr} { other._ptr = nullptr; }
260 
266  ~optional_ref() noexcept {}
267 
273  constexpr optional_ref &operator=(const optional_ref &other) noexcept { _ptr = other._ptr; return *this; }
279  constexpr optional_ref &operator=(optional_ref &&other) noexcept { _ptr = other._ptr; return *this; }
285  constexpr optional_ref &operator=(T &obj) noexcept { _ptr = &obj; return *this; }
286 
292  constexpr T *operator->() { return _ptr ? _ptr : throw null_pointer_exception{"pointer is NULL"}; }
298  constexpr const T *operator->() const { return _ptr ? _ptr : throw null_pointer_exception{"pointer is NULL"}; }
299 
305  constexpr T& operator*() { if (!_ptr) throw null_pointer_exception{"pointer is NULL"}; return *_ptr; }
311  constexpr const T& operator*() const { if (!_ptr) throw null_pointer_exception{"pointer is NULL"}; return *_ptr; }
312 
319  constexpr explicit operator bool() const noexcept { return _ptr != nullptr; }
325  constexpr bool has_value() const noexcept { return _ptr != nullptr; }
326 
332  constexpr T& value() & { return _ptr ? *_ptr : throw null_pointer_exception{"pointer is NULL"}; }
338  constexpr const T& value() const& { return _ptr ? *_ptr : throw null_pointer_exception{"pointer is NULL"}; }
339 
345  template<typename OT>
346  constexpr T value_or(OT&& dflt) const& noexcept
347  {
348  static_assert(std::is_copy_constructible<T>::value, "result is not copy constructable");
349  static_assert(std::is_convertible<OT&&, T>::value, "default is not convertible to result");
350  return _ptr == nullptr ? static_cast<T>(std::forward(dflt)) : *_ptr;
351  }
352 
357  constexpr void swap(optional_ref &other) noexcept
358  {
359  T *tmp = _ptr;
360  _ptr = other._ptr;
361  other._ptr = tmp;
362  }
367  constexpr void reset() noexcept { _ptr = nullptr; }
368 };
369 
379 template<typename CharT, typename Traits, typename T>
380 std::basic_ostream<CharT, Traits>& operator<<(std::basic_ostream<CharT, Traits>& out, const optional_ptr<T>& opt)
381 {
382  if (opt) out << *opt;
383  else out << "NULL";
384  return out;
385 }
395 template<typename CharT, typename Traits, typename T>
396 std::basic_ostream<CharT, Traits>& operator<<(std::basic_ostream<CharT, Traits>& out, const optional_ref<T>& opt)
397 {
398  if (opt) out << *opt;
399  else out << "NULL";
400  return out;
401 }
402 
411 template<typename T>
412 constexpr bool operator==(const optional_ref<T> &l, const optional_ref<T> &r)
413 {
414  return static_cast<bool>(l) == static_cast<bool>(r) && (!l || *l == *r);
415 }
424 template<typename T>
425 constexpr bool operator!=(const optional_ref<T> &l, const optional_ref<T> &r) { return !(l == r); }
426 
435 template<typename T>
436 constexpr bool operator<(const optional_ref<T> &l, const optional_ref<T> &r)
437 {
438  return static_cast<bool>(r) && (!l || *l < *r);
439 }
440 
449 template<typename T>
450 constexpr bool operator>(const optional_ref<T> &l, const optional_ref<T> &r) { return r < l; }
451 
460 template<typename T>
461 constexpr bool operator<=(const optional_ref<T> &l, const optional_ref<T> &r) { return !(r < l); }
462 
471 template<typename T>
472 constexpr bool operator>=(const optional_ref<T> &l, const optional_ref<T> &r) { return !(l < r); }
473 
483 template<typename T, typename U>
484 constexpr bool operator==(const optional_ref<T> &l, const U &r) { return l && *l == r; }
485 
495 template<typename T, typename U>
496 constexpr bool operator==(const T &l, const optional_ref<T> &r) { return r && l == *r; }
497 
507 template<typename T, typename U>
508 constexpr bool operator!=(const optional_ref<T> &l, U const &r) { return !l || !(*l == r); }
509 
519 template<typename T, typename U>
520 constexpr bool operator!=(const U &l, const optional_ref<T> &r) { return !r || !(l == *r); }
521 
531 template<typename T, typename U>
532 constexpr bool operator<(const optional_ref<T> &l, const U &r) { return !l || *l < r; }
533 
543 template<typename T, typename U>
544 constexpr bool operator<(const U &l, const optional_ref<T> &r) { return r && l < *r; }
545 
555 template<typename T, typename U>
556 constexpr bool operator>(const optional_ref<T> &l, const U &r) { return l && r < *l; }
557 
567 template<typename T, typename U>
568 constexpr bool operator>(const U &l, const optional_ref<T> &r) { return !r || *r < l; }
569 
579 template<typename T, typename U>
580 constexpr bool operator<=(const optional_ref<T> &l, const U &r) { return !l || !(r < *l); }
581 
591 template<typename T, typename U>
592 constexpr bool operator<=(const U &l, const optional_ref<T> &r) { return r && !(*r < l); }
593 
603 template<typename T, typename U>
604 constexpr bool operator>=(const optional_ref<T> &l, const U &r) { return l && !(*l < r); }
605 
615 template<typename T, typename U>
616 constexpr bool operator>=(const U &l, const optional_ref<T> &r) { return !r || !(l < *r); }
617 
625 template<typename T>
626 inline void swap(optional_ref<T> &l, optional_ref<T> &r) noexcept(noexcept(l.swap(r))) { l.swap(r); }
627 
628 } // end of servlet namespace
629 
630 #endif // SERVLET_OPTIONAL_H
T & reference
Type definition for reference type.
Definition: optional.h:232
Exception thrown on attempt to access nullptr object if this is possible to catch this attempt...
Definition: exception.h:55
constexpr bool is_owner() const noexcept
Checks whether this object is the owner of the contained pointer.
Definition: optional.h:154
constexpr const T * operator->() const
Accesses the contained value as a constant pointer.
Definition: optional.h:298
const T & const_reference
Type definition for constant reference type.
Definition: optional.h:236
constexpr T value_or(OT &&dflt) const &noexcept
Returns the contained value if this has a value, otherwise returns given value.
Definition: optional.h:346
T value_type
Type definition for value type.
Definition: optional.h:228
constexpr void reset() noexcept
If this object contains a valid pointer, delete that.
Definition: optional.h:203
constexpr optional_ptr & operator=(optional_ptr &&other) noexcept
Move assignment.
Definition: optional.h:111
constexpr optional_ref & operator=(optional_ref &&other) noexcept
Move assignment.
Definition: optional.h:279
Optional reference implementation.
Definition: optional.h:221
constexpr optional_ref & operator=(const optional_ref &other) noexcept
Replaces contents of this object with the contents of other.
Definition: optional.h:273
~optional_ref() noexcept
Destructor.
Definition: optional.h:266
constexpr optional_ref & operator=(T &obj) noexcept
Replaces contents of this object with the reference to other.
Definition: optional.h:285
Exception used in the mod_servlet.
constexpr optional_ptr & operator=(const optional_ptr &other)=delete
Copy is prohibited.
constexpr T & operator*()&
Accesses the contained pointer.
Definition: optional.h:176
constexpr T * operator->()
Accesses the contained value as a pointer.
Definition: optional.h:292
constexpr T & value()&
Accesses the contained value as a reference.
Definition: optional.h:332
T value_type
Type definition for value type.
Definition: optional.h:39
T * pointer
Type definition for pointer type.
Definition: optional.h:43
constexpr optional_ref(const optional_ref &other) noexcept
Copy constructor.
Definition: optional.h:254
constexpr void swap(optional_ref &other) noexcept
Swaps the contents with those of other.
Definition: optional.h:357
const T * const_pointer
Type definition for const pointer type.
Definition: optional.h:47
constexpr const T & value() const &
Accesses the contained value as a constant reference.
Definition: optional.h:338
~optional_ptr() noexcept
Destructor.
Definition: optional.h:83
constexpr bool has_value() const noexcept
Checks whether this object contains valid pointer.
Definition: optional.h:148
constexpr optional_ptr()
Default constructor.
Definition: optional.h:55
constexpr const T & operator*() const &
Accesses the contained pointer.
Definition: optional.h:183
constexpr void reset() noexcept
If this object contains a reference to an object, reset the pointer to that to nullptr.
Definition: optional.h:367
constexpr const T * operator->() const
const version of pointer accessor
Definition: optional.h:167
constexpr void clear()
Clears the object.
Definition: optional.h:92
constexpr T * operator->()
Accesses the contained pointer.
Definition: optional.h:161
constexpr void swap(optional_ptr &other) noexcept
Swaps the contents with those of other.
Definition: optional.h:189
constexpr optional_ref(optional_ref &&other) noexcept
Move constructor.
Definition: optional.h:259
constexpr optional_ptr & assign(T *ptr, bool owner=false)
Assigns new pointer to this object.
Definition: optional.h:129
constexpr optional_ptr(T *ptr, bool owner=false)
Constructor which creates the object with a given pointer and specified ownership.
Definition: optional.h:63
Class implements smart pointer with optional ownership.
Definition: optional.h:33
constexpr const T & operator*() const
Accesses the contained value as a constant reference.
Definition: optional.h:311
constexpr optional_ref(T &obj) noexcept
Constructs object that contains a reference to a given object,.
Definition: optional.h:248
constexpr bool has_value() const noexcept
Checks whether this object contains valid pointer.
Definition: optional.h:325
constexpr T & operator*()
Accesses the contained value as a reference.
Definition: optional.h:305
constexpr optional_ref() noexcept
Default constructor.
Definition: optional.h:243
constexpr optional_ptr(optional_ptr &&other)
Move constructor.
Definition: optional.h:74