File: optional

package info (click to toggle)
polymake 4.14-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 35,888 kB
  • sloc: cpp: 168,933; perl: 43,407; javascript: 31,575; ansic: 3,007; java: 2,654; python: 632; sh: 268; xml: 117; makefile: 61
file content (119 lines) | stat: -rw-r--r-- 2,490 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#ifndef POLYMAKE_OPTIONAL_
#define POLYMAKE_OPTIONAL_

// Until we have migrated to C++17, we have to use std::experimental::optional.
// While GCC comes with a fully functional implementation,
// clang libc++ has a broken one in versions up to 6 and completely lacks it from version 7 upwards.
// Moreover, older clangs produce strange errors even in combination with libstdc++.
// For this configuration, we include a minimal implementation just covering our needs.

#if __cplusplus < 201703L

#if defined(__clang__) && (defined(_LIBCPP_STD_VER) || __clang_major__ < 4)

#include "polymake/internal/type_union.h"

namespace pm {

struct nullopt_t
{
   enum class Construct { Token };
   explicit constexpr nullopt_t(Construct) { }
};

constexpr nullopt_t nullopt { nullopt_t::Construct::Token };

template <typename T>
class optional
   : private type_union<T> {
   using base_t = type_union<T>;
public:
   optional(nullopt_t) noexcept {}

   explicit optional(const T& x)
      : base_t(x) {}

   explicit optional(T&& x)
      : base_t(std::forward<T>(x)) {}

   explicit operator bool() const noexcept
   {
      return this->valid();
   }

   const T& value() const&
   {
      if (const T* ptr = this->template as<T>())
         return *ptr;
      throw std::logic_error("bad optional access");
   }

   T& value() &
   {
      if (T* ptr = this->template as<T>())
         return *ptr;
      throw std::logic_error("bad optional access");
   }

   T&& value() &&
   {
      if (T* ptr = this->template as<T>())
         return std::move(*ptr);
      throw std::logic_error("bad optional access");
   }
};

template <typename T>
optional<pure_type_t<T>> make_optional(T&& x)
{
   return optional<pure_type_t<T>>{ std::forward<T>(x) };
}

}
namespace polymake {
using pm::optional;
using pm::nullopt;
using pm::make_optional;
}

#else // GCC or clang >= 4

# include <experimental/optional>

namespace polymake {
using std::experimental::optional;
using std::experimental::nullopt;
using std::experimental::make_optional;
}
namespace pm {
using std::experimental::optional;
using std::experimental::nullopt;
using std::experimental::make_optional;
}

#endif

#else

#include <optional>

namespace polymake {
using std::optional;
using std::nullopt;
using std::make_optional;
}
namespace pm {
using std::optional;
using std::nullopt;
using std::make_optional;
}

#endif

#endif // POLYMAKE_OPTIONAL_

// Local Variables:
// mode:C++
// c-basic-offset:3
// indent-tabs-mode:nil
// End: