Spicy
optional.h
1 // Copyright (c) 2020-2021 by the Zeek Project. See LICENSE for details.
2 
3 #pragma once
4 
5 #include <string>
6 
7 #include <hilti/rt/extension-points.h>
8 #include <hilti/rt/util.h>
9 
10 namespace hilti::rt {
11 
12 namespace detail::adl {
13 template<typename T>
14 inline std::string to_string(std::optional<T> x, adl::tag /*unused*/) {
15  return x ? hilti::rt::to_string(*x) : "(not set)";
16 }
17 
18 } // namespace detail::adl
19 
20 namespace optional {
21 
22 struct Unset : public std::exception {}; // Internal exception to signal access to optional that may expectedly by unset
23 
24 template<class T>
25 inline auto& value(const std::optional<T>& t, const char* location) {
26  if ( t.has_value() )
27  return t.value();
28 
29  throw UnsetOptional("unset optional value", location);
30 }
31 
32 template<class T>
33 inline auto& value(std::optional<T>& t, const char* location) {
34  if ( t.has_value() )
35  return t.value();
36 
37  throw UnsetOptional("unset optional value", location);
38 }
39 
40 template<class T>
41 inline auto& valueOrInit(std::optional<T>& t, const T& default_) {
42  if ( ! t.has_value() )
43  t = default_;
44 
45  return t.value();
46 }
47 
48 template<class T>
49 inline auto& valueOrInit(std::optional<T>& t) {
50  if ( ! t.has_value() )
51  t.emplace();
52 
53  return t.value();
54 }
55 
56 template<class T>
57 inline auto& tryValue(const std::optional<T>& t) {
58  if ( t.has_value() )
59  return t.value();
60 
61  throw Unset();
62 }
63 
64 } // namespace optional
65 
66 template<>
67 inline std::string detail::to_string_for_print<std::optional<std::string>>(const std::optional<std::string>& x) {
68  return x ? *x : "(not set)";
69 }
70 
71 template<>
72 inline std::string detail::to_string_for_print<std::optional<std::string_view>>(
73  const std::optional<std::string_view>& x) {
74  return x ? std::string(*x) : "(not set)";
75 }
76 
77 } // namespace hilti::rt
78 
79 namespace std {
80 
81 // Provide operator<< overload for optionals that have a custom HILTI-side to_string() conversion.
82 template<typename T>
83 inline auto operator<<(std::ostream& out, const std::optional<T>& x)
84  -> decltype(::hilti::rt::detail::adl::to_string(x, ::hilti::rt::detail::adl::tag()), out) {
85  out << ::hilti::rt::to_string(x);
86  return out;
87 }
88 
89 } // namespace std
std::string to_string(T &&x)
Definition: extension-points.h:26
Definition: any.h:7
Definition: optional.h:79
Definition: optional.h:22
Definition: extension-points.h:12
Definition: location.h:86