grpc 1.26.0 → 1.27.0.pre1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of grpc might be problematic. Click here for more details.

Files changed (209) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +1654 -1519
  3. data/etc/roots.pem +44 -0
  4. data/include/grpc/grpc_security.h +37 -15
  5. data/include/grpc/grpc_security_constants.h +27 -0
  6. data/include/grpc/impl/codegen/grpc_types.h +14 -0
  7. data/include/grpc/impl/codegen/port_platform.h +1 -1
  8. data/src/core/ext/filters/client_channel/client_channel.cc +0 -20
  9. data/src/core/ext/filters/client_channel/http_proxy.cc +4 -4
  10. data/src/core/ext/filters/client_channel/lb_policy.cc +4 -3
  11. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +191 -201
  12. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.cc +89 -0
  13. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.h +40 -0
  14. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc +3 -2
  15. data/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc +88 -121
  16. data/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h +28 -57
  17. data/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +0 -7
  18. data/src/core/ext/filters/client_channel/lb_policy/xds/cds.cc +8 -9
  19. data/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +53 -34
  20. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +18 -5
  21. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc +24 -19
  22. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h +2 -1
  23. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc +4 -2
  24. data/src/core/ext/filters/client_channel/server_address.cc +6 -9
  25. data/src/core/ext/filters/client_channel/server_address.h +3 -10
  26. data/src/core/ext/filters/client_channel/xds/xds_api.cc +394 -150
  27. data/src/core/ext/filters/client_channel/xds/xds_api.h +75 -35
  28. data/src/core/ext/filters/client_channel/xds/xds_bootstrap.cc +59 -22
  29. data/src/core/ext/filters/client_channel/xds/xds_bootstrap.h +13 -9
  30. data/src/core/ext/filters/client_channel/xds/xds_channel_secure.cc +8 -6
  31. data/src/core/ext/filters/client_channel/xds/xds_client.cc +456 -175
  32. data/src/core/ext/filters/client_channel/xds/xds_client.h +33 -21
  33. data/src/core/ext/filters/client_channel/xds/xds_client_stats.cc +5 -8
  34. data/src/core/ext/filters/client_channel/xds/xds_client_stats.h +18 -24
  35. data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +2 -2
  36. data/src/core/ext/upb-generated/src/proto/grpc/lb/v1/load_balancer.upb.c +13 -5
  37. data/src/core/ext/upb-generated/src/proto/grpc/lb/v1/load_balancer.upb.h +34 -0
  38. data/src/core/lib/channel/channelz.h +11 -1
  39. data/src/core/lib/gpr/time_precise.cc +1 -1
  40. data/src/core/lib/gprpp/optional.h +26 -0
  41. data/src/core/lib/gprpp/string_view.h +14 -10
  42. data/src/core/lib/iomgr/executor.cc +1 -1
  43. data/src/core/lib/iomgr/fork_posix.cc +4 -0
  44. data/src/core/lib/iomgr/poller/eventmanager_libuv.cc +87 -0
  45. data/src/core/lib/iomgr/poller/eventmanager_libuv.h +88 -0
  46. data/src/core/lib/iomgr/socket_utils_common_posix.cc +14 -0
  47. data/src/core/lib/iomgr/socket_utils_posix.h +12 -0
  48. data/src/core/lib/iomgr/tcp_custom.h +3 -0
  49. data/src/core/lib/iomgr/tcp_posix.cc +607 -56
  50. data/src/core/lib/iomgr/tcp_server_custom.cc +15 -2
  51. data/src/core/lib/iomgr/tcp_server_utils_posix_common.cc +8 -0
  52. data/src/core/lib/json/json.h +11 -1
  53. data/src/core/lib/json/json_reader.cc +206 -28
  54. data/src/core/lib/json/json_writer.cc +111 -24
  55. data/src/core/lib/security/credentials/composite/composite_credentials.cc +7 -0
  56. data/src/core/lib/security/credentials/composite/composite_credentials.h +5 -1
  57. data/src/core/lib/security/credentials/credentials.h +10 -1
  58. data/src/core/lib/security/credentials/fake/fake_credentials.h +2 -1
  59. data/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc +1 -1
  60. data/src/core/lib/security/credentials/plugin/plugin_credentials.cc +6 -4
  61. data/src/core/lib/security/credentials/plugin/plugin_credentials.h +2 -1
  62. data/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc +20 -0
  63. data/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h +8 -0
  64. data/src/core/lib/security/credentials/tls/{spiffe_credentials.cc → tls_credentials.cc} +23 -24
  65. data/src/core/lib/security/credentials/tls/{spiffe_credentials.h → tls_credentials.h} +9 -9
  66. data/src/core/lib/security/security_connector/alts/alts_security_connector.cc +13 -0
  67. data/src/core/lib/security/security_connector/fake/fake_security_connector.cc +22 -2
  68. data/src/core/lib/security/security_connector/load_system_roots_fallback.cc +2 -2
  69. data/src/core/lib/security/security_connector/load_system_roots_linux.cc +2 -2
  70. data/src/core/lib/security/security_connector/local/local_security_connector.cc +30 -3
  71. data/src/core/lib/security/security_connector/ssl_utils.cc +45 -3
  72. data/src/core/lib/security/security_connector/ssl_utils.h +12 -0
  73. data/src/core/lib/security/security_connector/tls/{spiffe_security_connector.cc → tls_security_connector.cc} +82 -69
  74. data/src/core/lib/security/security_connector/tls/{spiffe_security_connector.h → tls_security_connector.h} +17 -18
  75. data/src/core/lib/security/transport/client_auth_filter.cc +33 -0
  76. data/src/core/lib/surface/completion_queue.cc +22 -1
  77. data/src/core/lib/surface/version.cc +1 -1
  78. data/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc +11 -1
  79. data/src/core/tsi/alts/handshaker/alts_tsi_handshaker.h +1 -1
  80. data/src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.cc +3 -3
  81. data/src/core/tsi/fake_transport_security.cc +7 -3
  82. data/src/core/tsi/fake_transport_security.h +2 -0
  83. data/src/core/tsi/ssl_transport_security.cc +144 -8
  84. data/src/core/tsi/ssl_transport_security.h +15 -1
  85. data/src/core/tsi/transport_security.cc +13 -0
  86. data/src/core/tsi/transport_security_grpc.cc +2 -2
  87. data/src/core/tsi/transport_security_grpc.h +2 -2
  88. data/src/core/tsi/transport_security_interface.h +12 -0
  89. data/src/ruby/bin/math_pb.rb +5 -5
  90. data/src/ruby/ext/grpc/rb_call_credentials.c +4 -1
  91. data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +2 -0
  92. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +4 -1
  93. data/src/ruby/lib/grpc/version.rb +1 -1
  94. data/src/ruby/pb/grpc/health/v1/health_pb.rb +3 -3
  95. data/src/ruby/pb/src/proto/grpc/testing/empty_pb.rb +1 -1
  96. data/src/ruby/pb/src/proto/grpc/testing/messages_pb.rb +23 -13
  97. data/third_party/abseil-cpp/absl/algorithm/algorithm.h +159 -0
  98. data/third_party/abseil-cpp/absl/base/attributes.h +609 -0
  99. data/third_party/abseil-cpp/absl/base/call_once.h +226 -0
  100. data/third_party/abseil-cpp/absl/base/casts.h +184 -0
  101. data/third_party/abseil-cpp/absl/base/config.h +622 -0
  102. data/third_party/abseil-cpp/absl/base/const_init.h +76 -0
  103. data/third_party/abseil-cpp/absl/base/dynamic_annotations.cc +129 -0
  104. data/third_party/abseil-cpp/absl/base/dynamic_annotations.h +389 -0
  105. data/third_party/abseil-cpp/absl/base/internal/atomic_hook.h +179 -0
  106. data/third_party/abseil-cpp/absl/base/internal/bits.h +218 -0
  107. data/third_party/abseil-cpp/absl/base/internal/cycleclock.cc +107 -0
  108. data/third_party/abseil-cpp/absl/base/internal/cycleclock.h +94 -0
  109. data/third_party/abseil-cpp/absl/base/internal/endian.h +266 -0
  110. data/third_party/abseil-cpp/absl/base/internal/hide_ptr.h +51 -0
  111. data/third_party/abseil-cpp/absl/base/internal/identity.h +37 -0
  112. data/third_party/abseil-cpp/absl/base/internal/inline_variable.h +107 -0
  113. data/third_party/abseil-cpp/absl/base/internal/invoke.h +187 -0
  114. data/third_party/abseil-cpp/absl/base/internal/low_level_scheduling.h +107 -0
  115. data/third_party/abseil-cpp/absl/base/internal/per_thread_tls.h +52 -0
  116. data/third_party/abseil-cpp/absl/base/internal/raw_logging.cc +237 -0
  117. data/third_party/abseil-cpp/absl/base/internal/raw_logging.h +179 -0
  118. data/third_party/abseil-cpp/absl/base/internal/scheduling_mode.h +58 -0
  119. data/third_party/abseil-cpp/absl/base/internal/spinlock.cc +233 -0
  120. data/third_party/abseil-cpp/absl/base/internal/spinlock.h +243 -0
  121. data/third_party/abseil-cpp/absl/base/internal/spinlock_akaros.inc +35 -0
  122. data/third_party/abseil-cpp/absl/base/internal/spinlock_linux.inc +67 -0
  123. data/third_party/abseil-cpp/absl/base/internal/spinlock_posix.inc +46 -0
  124. data/third_party/abseil-cpp/absl/base/internal/spinlock_wait.cc +81 -0
  125. data/third_party/abseil-cpp/absl/base/internal/spinlock_wait.h +93 -0
  126. data/third_party/abseil-cpp/absl/base/internal/spinlock_win32.inc +37 -0
  127. data/third_party/abseil-cpp/absl/base/internal/sysinfo.cc +414 -0
  128. data/third_party/abseil-cpp/absl/base/internal/sysinfo.h +66 -0
  129. data/third_party/abseil-cpp/absl/base/internal/thread_annotations.h +271 -0
  130. data/third_party/abseil-cpp/absl/base/internal/thread_identity.cc +140 -0
  131. data/third_party/abseil-cpp/absl/base/internal/thread_identity.h +250 -0
  132. data/third_party/abseil-cpp/absl/base/internal/throw_delegate.cc +108 -0
  133. data/third_party/abseil-cpp/absl/base/internal/throw_delegate.h +75 -0
  134. data/third_party/abseil-cpp/absl/base/internal/tsan_mutex_interface.h +66 -0
  135. data/third_party/abseil-cpp/absl/base/internal/unaligned_access.h +158 -0
  136. data/third_party/abseil-cpp/absl/base/internal/unscaledcycleclock.cc +103 -0
  137. data/third_party/abseil-cpp/absl/base/internal/unscaledcycleclock.h +124 -0
  138. data/third_party/abseil-cpp/absl/base/log_severity.cc +27 -0
  139. data/third_party/abseil-cpp/absl/base/log_severity.h +121 -0
  140. data/third_party/abseil-cpp/absl/base/macros.h +220 -0
  141. data/third_party/abseil-cpp/absl/base/optimization.h +181 -0
  142. data/third_party/abseil-cpp/absl/base/options.h +214 -0
  143. data/third_party/abseil-cpp/absl/base/policy_checks.h +111 -0
  144. data/third_party/abseil-cpp/absl/base/port.h +26 -0
  145. data/third_party/abseil-cpp/absl/base/thread_annotations.h +280 -0
  146. data/third_party/abseil-cpp/absl/container/inlined_vector.h +848 -0
  147. data/third_party/abseil-cpp/absl/container/internal/compressed_tuple.h +265 -0
  148. data/third_party/abseil-cpp/absl/container/internal/inlined_vector.h +892 -0
  149. data/third_party/abseil-cpp/absl/memory/memory.h +695 -0
  150. data/third_party/abseil-cpp/absl/meta/type_traits.h +759 -0
  151. data/third_party/abseil-cpp/absl/numeric/int128.cc +404 -0
  152. data/third_party/abseil-cpp/absl/numeric/int128.h +1091 -0
  153. data/third_party/abseil-cpp/absl/numeric/int128_have_intrinsic.inc +302 -0
  154. data/third_party/abseil-cpp/absl/numeric/int128_no_intrinsic.inc +308 -0
  155. data/third_party/abseil-cpp/absl/strings/ascii.cc +200 -0
  156. data/third_party/abseil-cpp/absl/strings/ascii.h +241 -0
  157. data/third_party/abseil-cpp/absl/strings/charconv.cc +985 -0
  158. data/third_party/abseil-cpp/absl/strings/charconv.h +119 -0
  159. data/third_party/abseil-cpp/absl/strings/escaping.cc +949 -0
  160. data/third_party/abseil-cpp/absl/strings/escaping.h +164 -0
  161. data/third_party/abseil-cpp/absl/strings/internal/char_map.h +156 -0
  162. data/third_party/abseil-cpp/absl/strings/internal/charconv_bigint.cc +359 -0
  163. data/third_party/abseil-cpp/absl/strings/internal/charconv_bigint.h +421 -0
  164. data/third_party/abseil-cpp/absl/strings/internal/charconv_parse.cc +504 -0
  165. data/third_party/abseil-cpp/absl/strings/internal/charconv_parse.h +99 -0
  166. data/third_party/abseil-cpp/absl/strings/internal/escaping.cc +180 -0
  167. data/third_party/abseil-cpp/absl/strings/internal/escaping.h +58 -0
  168. data/third_party/abseil-cpp/absl/strings/internal/memutil.cc +112 -0
  169. data/third_party/abseil-cpp/absl/strings/internal/memutil.h +148 -0
  170. data/third_party/abseil-cpp/absl/strings/internal/ostringstream.cc +36 -0
  171. data/third_party/abseil-cpp/absl/strings/internal/ostringstream.h +89 -0
  172. data/third_party/abseil-cpp/absl/strings/internal/resize_uninitialized.h +73 -0
  173. data/third_party/abseil-cpp/absl/strings/internal/stl_type_traits.h +248 -0
  174. data/third_party/abseil-cpp/absl/strings/internal/str_join_internal.h +314 -0
  175. data/third_party/abseil-cpp/absl/strings/internal/str_split_internal.h +455 -0
  176. data/third_party/abseil-cpp/absl/strings/internal/utf8.cc +53 -0
  177. data/third_party/abseil-cpp/absl/strings/internal/utf8.h +50 -0
  178. data/third_party/abseil-cpp/absl/strings/match.cc +40 -0
  179. data/third_party/abseil-cpp/absl/strings/match.h +90 -0
  180. data/third_party/abseil-cpp/absl/strings/numbers.cc +916 -0
  181. data/third_party/abseil-cpp/absl/strings/numbers.h +263 -0
  182. data/third_party/abseil-cpp/absl/strings/str_cat.cc +246 -0
  183. data/third_party/abseil-cpp/absl/strings/str_cat.h +408 -0
  184. data/third_party/abseil-cpp/absl/strings/str_join.h +293 -0
  185. data/third_party/abseil-cpp/absl/strings/str_replace.cc +82 -0
  186. data/third_party/abseil-cpp/absl/strings/str_replace.h +219 -0
  187. data/third_party/abseil-cpp/absl/strings/str_split.cc +139 -0
  188. data/third_party/abseil-cpp/absl/strings/str_split.h +513 -0
  189. data/third_party/abseil-cpp/absl/strings/string_view.cc +235 -0
  190. data/third_party/abseil-cpp/absl/strings/string_view.h +615 -0
  191. data/third_party/abseil-cpp/absl/strings/strip.h +91 -0
  192. data/third_party/abseil-cpp/absl/strings/substitute.cc +171 -0
  193. data/third_party/abseil-cpp/absl/strings/substitute.h +693 -0
  194. data/third_party/abseil-cpp/absl/types/bad_optional_access.cc +48 -0
  195. data/third_party/abseil-cpp/absl/types/bad_optional_access.h +78 -0
  196. data/third_party/abseil-cpp/absl/types/internal/optional.h +396 -0
  197. data/third_party/abseil-cpp/absl/types/internal/span.h +128 -0
  198. data/third_party/abseil-cpp/absl/types/optional.h +776 -0
  199. data/third_party/abseil-cpp/absl/types/span.h +713 -0
  200. data/third_party/abseil-cpp/absl/utility/utility.h +350 -0
  201. data/third_party/upb/upb/decode.c +4 -0
  202. data/third_party/upb/upb/port.c +0 -1
  203. data/third_party/upb/upb/port_def.inc +1 -3
  204. data/third_party/upb/upb/table.c +2 -1
  205. metadata +147 -43
  206. data/src/core/lib/json/json_common.h +0 -34
  207. data/src/core/lib/json/json_reader.h +0 -146
  208. data/src/core/lib/json/json_string.cc +0 -367
  209. data/src/core/lib/json/json_writer.h +0 -84
@@ -0,0 +1,128 @@
1
+ //
2
+ // Copyright 2019 The Abseil Authors.
3
+ //
4
+ // Licensed under the Apache License, Version 2.0 (the "License");
5
+ // you may not use this file except in compliance with the License.
6
+ // You may obtain a copy of the License at
7
+ //
8
+ // https://www.apache.org/licenses/LICENSE-2.0
9
+ //
10
+ // Unless required by applicable law or agreed to in writing, software
11
+ // distributed under the License is distributed on an "AS IS" BASIS,
12
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ // See the License for the specific language governing permissions and
14
+ // limitations under the License.
15
+ //
16
+ #ifndef ABSL_TYPES_INTERNAL_SPAN_H_
17
+ #define ABSL_TYPES_INTERNAL_SPAN_H_
18
+
19
+ #include <algorithm>
20
+ #include <cstddef>
21
+ #include <string>
22
+ #include <type_traits>
23
+
24
+ #include "absl/algorithm/algorithm.h"
25
+ #include "absl/base/internal/throw_delegate.h"
26
+ #include "absl/meta/type_traits.h"
27
+
28
+ namespace absl {
29
+ ABSL_NAMESPACE_BEGIN
30
+
31
+ namespace span_internal {
32
+ // A constexpr min function
33
+ constexpr size_t Min(size_t a, size_t b) noexcept { return a < b ? a : b; }
34
+
35
+ // Wrappers for access to container data pointers.
36
+ template <typename C>
37
+ constexpr auto GetDataImpl(C& c, char) noexcept // NOLINT(runtime/references)
38
+ -> decltype(c.data()) {
39
+ return c.data();
40
+ }
41
+
42
+ // Before C++17, std::string::data returns a const char* in all cases.
43
+ inline char* GetDataImpl(std::string& s, // NOLINT(runtime/references)
44
+ int) noexcept {
45
+ return &s[0];
46
+ }
47
+
48
+ template <typename C>
49
+ constexpr auto GetData(C& c) noexcept // NOLINT(runtime/references)
50
+ -> decltype(GetDataImpl(c, 0)) {
51
+ return GetDataImpl(c, 0);
52
+ }
53
+
54
+ // Detection idioms for size() and data().
55
+ template <typename C>
56
+ using HasSize =
57
+ std::is_integral<absl::decay_t<decltype(std::declval<C&>().size())>>;
58
+
59
+ // We want to enable conversion from vector<T*> to Span<const T* const> but
60
+ // disable conversion from vector<Derived> to Span<Base>. Here we use
61
+ // the fact that U** is convertible to Q* const* if and only if Q is the same
62
+ // type or a more cv-qualified version of U. We also decay the result type of
63
+ // data() to avoid problems with classes which have a member function data()
64
+ // which returns a reference.
65
+ template <typename T, typename C>
66
+ using HasData =
67
+ std::is_convertible<absl::decay_t<decltype(GetData(std::declval<C&>()))>*,
68
+ T* const*>;
69
+
70
+ // Extracts value type from a Container
71
+ template <typename C>
72
+ struct ElementType {
73
+ using type = typename absl::remove_reference_t<C>::value_type;
74
+ };
75
+
76
+ template <typename T, size_t N>
77
+ struct ElementType<T (&)[N]> {
78
+ using type = T;
79
+ };
80
+
81
+ template <typename C>
82
+ using ElementT = typename ElementType<C>::type;
83
+
84
+ template <typename T>
85
+ using EnableIfMutable =
86
+ typename std::enable_if<!std::is_const<T>::value, int>::type;
87
+
88
+ template <template <typename> class SpanT, typename T>
89
+ bool EqualImpl(SpanT<T> a, SpanT<T> b) {
90
+ static_assert(std::is_const<T>::value, "");
91
+ return absl::equal(a.begin(), a.end(), b.begin(), b.end());
92
+ }
93
+
94
+ template <template <typename> class SpanT, typename T>
95
+ bool LessThanImpl(SpanT<T> a, SpanT<T> b) {
96
+ // We can't use value_type since that is remove_cv_t<T>, so we go the long way
97
+ // around.
98
+ static_assert(std::is_const<T>::value, "");
99
+ return std::lexicographical_compare(a.begin(), a.end(), b.begin(), b.end());
100
+ }
101
+
102
+ // The `IsConvertible` classes here are needed because of the
103
+ // `std::is_convertible` bug in libcxx when compiled with GCC. This build
104
+ // configuration is used by Android NDK toolchain. Reference link:
105
+ // https://bugs.llvm.org/show_bug.cgi?id=27538.
106
+ template <typename From, typename To>
107
+ struct IsConvertibleHelper {
108
+ private:
109
+ static std::true_type testval(To);
110
+ static std::false_type testval(...);
111
+
112
+ public:
113
+ using type = decltype(testval(std::declval<From>()));
114
+ };
115
+
116
+ template <typename From, typename To>
117
+ struct IsConvertible : IsConvertibleHelper<From, To>::type {};
118
+
119
+ // TODO(zhangxy): replace `IsConvertible` with `std::is_convertible` once the
120
+ // older version of libcxx is not supported.
121
+ template <typename From, typename To>
122
+ using EnableIfConvertibleTo =
123
+ typename std::enable_if<IsConvertible<From, To>::value>::type;
124
+ } // namespace span_internal
125
+ ABSL_NAMESPACE_END
126
+ } // namespace absl
127
+
128
+ #endif // ABSL_TYPES_INTERNAL_SPAN_H_
@@ -0,0 +1,776 @@
1
+ // Copyright 2017 The Abseil Authors.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // https://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+ //
15
+ // -----------------------------------------------------------------------------
16
+ // optional.h
17
+ // -----------------------------------------------------------------------------
18
+ //
19
+ // This header file defines the `absl::optional` type for holding a value which
20
+ // may or may not be present. This type is useful for providing value semantics
21
+ // for operations that may either wish to return or hold "something-or-nothing".
22
+ //
23
+ // Example:
24
+ //
25
+ // // A common way to signal operation failure is to provide an output
26
+ // // parameter and a bool return type:
27
+ // bool AcquireResource(const Input&, Resource * out);
28
+ //
29
+ // // Providing an absl::optional return type provides a cleaner API:
30
+ // absl::optional<Resource> AcquireResource(const Input&);
31
+ //
32
+ // `absl::optional` is a C++11 compatible version of the C++17 `std::optional`
33
+ // abstraction and is designed to be a drop-in replacement for code compliant
34
+ // with C++17.
35
+ #ifndef ABSL_TYPES_OPTIONAL_H_
36
+ #define ABSL_TYPES_OPTIONAL_H_
37
+
38
+ #include "absl/base/config.h" // TODO(calabrese) IWYU removal?
39
+ #include "absl/utility/utility.h"
40
+
41
+ #ifdef ABSL_USES_STD_OPTIONAL
42
+
43
+ #include <optional> // IWYU pragma: export
44
+
45
+ namespace absl {
46
+ ABSL_NAMESPACE_BEGIN
47
+ using std::bad_optional_access;
48
+ using std::optional;
49
+ using std::make_optional;
50
+ using std::nullopt_t;
51
+ using std::nullopt;
52
+ ABSL_NAMESPACE_END
53
+ } // namespace absl
54
+
55
+ #else // ABSL_USES_STD_OPTIONAL
56
+
57
+ #include <cassert>
58
+ #include <functional>
59
+ #include <initializer_list>
60
+ #include <type_traits>
61
+ #include <utility>
62
+
63
+ #include "absl/base/attributes.h"
64
+ #include "absl/base/internal/inline_variable.h"
65
+ #include "absl/meta/type_traits.h"
66
+ #include "absl/types/bad_optional_access.h"
67
+ #include "absl/types/internal/optional.h"
68
+
69
+ namespace absl {
70
+ ABSL_NAMESPACE_BEGIN
71
+
72
+ // nullopt_t
73
+ //
74
+ // Class type for `absl::nullopt` used to indicate an `absl::optional<T>` type
75
+ // that does not contain a value.
76
+ struct nullopt_t {
77
+ // It must not be default-constructible to avoid ambiguity for opt = {}.
78
+ explicit constexpr nullopt_t(optional_internal::init_t) noexcept {}
79
+ };
80
+
81
+ // nullopt
82
+ //
83
+ // A tag constant of type `absl::nullopt_t` used to indicate an empty
84
+ // `absl::optional` in certain functions, such as construction or assignment.
85
+ ABSL_INTERNAL_INLINE_CONSTEXPR(nullopt_t, nullopt,
86
+ nullopt_t(optional_internal::init_t()));
87
+
88
+ // -----------------------------------------------------------------------------
89
+ // absl::optional
90
+ // -----------------------------------------------------------------------------
91
+ //
92
+ // A value of type `absl::optional<T>` holds either a value of `T` or an
93
+ // "empty" value. When it holds a value of `T`, it stores it as a direct
94
+ // sub-object, so `sizeof(optional<T>)` is approximately
95
+ // `sizeof(T) + sizeof(bool)`.
96
+ //
97
+ // This implementation is based on the specification in the latest draft of the
98
+ // C++17 `std::optional` specification as of May 2017, section 20.6.
99
+ //
100
+ // Differences between `absl::optional<T>` and `std::optional<T>` include:
101
+ //
102
+ // * `constexpr` is not used for non-const member functions.
103
+ // (dependency on some differences between C++11 and C++14.)
104
+ // * `absl::nullopt` and `absl::in_place` are not declared `constexpr`. We
105
+ // need the inline variable support in C++17 for external linkage.
106
+ // * Throws `absl::bad_optional_access` instead of
107
+ // `std::bad_optional_access`.
108
+ // * `make_optional()` cannot be declared `constexpr` due to the absence of
109
+ // guaranteed copy elision.
110
+ // * The move constructor's `noexcept` specification is stronger, i.e. if the
111
+ // default allocator is non-throwing (via setting
112
+ // `ABSL_ALLOCATOR_NOTHROW`), it evaluates to `noexcept(true)`, because
113
+ // we assume
114
+ // a) move constructors should only throw due to allocation failure and
115
+ // b) if T's move constructor allocates, it uses the same allocation
116
+ // function as the default allocator.
117
+ //
118
+ template <typename T>
119
+ class optional : private optional_internal::optional_data<T>,
120
+ private optional_internal::optional_ctor_base<
121
+ optional_internal::ctor_copy_traits<T>::traits>,
122
+ private optional_internal::optional_assign_base<
123
+ optional_internal::assign_copy_traits<T>::traits> {
124
+ using data_base = optional_internal::optional_data<T>;
125
+
126
+ public:
127
+ typedef T value_type;
128
+
129
+ // Constructors
130
+
131
+ // Constructs an `optional` holding an empty value, NOT a default constructed
132
+ // `T`.
133
+ constexpr optional() noexcept {}
134
+
135
+ // Constructs an `optional` initialized with `nullopt` to hold an empty value.
136
+ constexpr optional(nullopt_t) noexcept {} // NOLINT(runtime/explicit)
137
+
138
+ // Copy constructor, standard semantics
139
+ optional(const optional& src) = default;
140
+
141
+ // Move constructor, standard semantics
142
+ optional(optional&& src) = default;
143
+
144
+ // Constructs a non-empty `optional` direct-initialized value of type `T` from
145
+ // the arguments `std::forward<Args>(args)...` within the `optional`.
146
+ // (The `in_place_t` is a tag used to indicate that the contained object
147
+ // should be constructed in-place.)
148
+ template <typename InPlaceT, typename... Args,
149
+ absl::enable_if_t<absl::conjunction<
150
+ std::is_same<InPlaceT, in_place_t>,
151
+ std::is_constructible<T, Args&&...> >::value>* = nullptr>
152
+ constexpr explicit optional(InPlaceT, Args&&... args)
153
+ : data_base(in_place_t(), absl::forward<Args>(args)...) {}
154
+
155
+ // Constructs a non-empty `optional` direct-initialized value of type `T` from
156
+ // the arguments of an initializer_list and `std::forward<Args>(args)...`.
157
+ // (The `in_place_t` is a tag used to indicate that the contained object
158
+ // should be constructed in-place.)
159
+ template <typename U, typename... Args,
160
+ typename = typename std::enable_if<std::is_constructible<
161
+ T, std::initializer_list<U>&, Args&&...>::value>::type>
162
+ constexpr explicit optional(in_place_t, std::initializer_list<U> il,
163
+ Args&&... args)
164
+ : data_base(in_place_t(), il, absl::forward<Args>(args)...) {
165
+ }
166
+
167
+ // Value constructor (implicit)
168
+ template <
169
+ typename U = T,
170
+ typename std::enable_if<
171
+ absl::conjunction<absl::negation<std::is_same<
172
+ in_place_t, typename std::decay<U>::type> >,
173
+ absl::negation<std::is_same<
174
+ optional<T>, typename std::decay<U>::type> >,
175
+ std::is_convertible<U&&, T>,
176
+ std::is_constructible<T, U&&> >::value,
177
+ bool>::type = false>
178
+ constexpr optional(U&& v) : data_base(in_place_t(), absl::forward<U>(v)) {}
179
+
180
+ // Value constructor (explicit)
181
+ template <
182
+ typename U = T,
183
+ typename std::enable_if<
184
+ absl::conjunction<absl::negation<std::is_same<
185
+ in_place_t, typename std::decay<U>::type>>,
186
+ absl::negation<std::is_same<
187
+ optional<T>, typename std::decay<U>::type>>,
188
+ absl::negation<std::is_convertible<U&&, T>>,
189
+ std::is_constructible<T, U&&>>::value,
190
+ bool>::type = false>
191
+ explicit constexpr optional(U&& v)
192
+ : data_base(in_place_t(), absl::forward<U>(v)) {}
193
+
194
+ // Converting copy constructor (implicit)
195
+ template <typename U,
196
+ typename std::enable_if<
197
+ absl::conjunction<
198
+ absl::negation<std::is_same<T, U> >,
199
+ std::is_constructible<T, const U&>,
200
+ absl::negation<
201
+ optional_internal::
202
+ is_constructible_convertible_from_optional<T, U> >,
203
+ std::is_convertible<const U&, T> >::value,
204
+ bool>::type = false>
205
+ optional(const optional<U>& rhs) {
206
+ if (rhs) {
207
+ this->construct(*rhs);
208
+ }
209
+ }
210
+
211
+ // Converting copy constructor (explicit)
212
+ template <typename U,
213
+ typename std::enable_if<
214
+ absl::conjunction<
215
+ absl::negation<std::is_same<T, U>>,
216
+ std::is_constructible<T, const U&>,
217
+ absl::negation<
218
+ optional_internal::
219
+ is_constructible_convertible_from_optional<T, U>>,
220
+ absl::negation<std::is_convertible<const U&, T>>>::value,
221
+ bool>::type = false>
222
+ explicit optional(const optional<U>& rhs) {
223
+ if (rhs) {
224
+ this->construct(*rhs);
225
+ }
226
+ }
227
+
228
+ // Converting move constructor (implicit)
229
+ template <typename U,
230
+ typename std::enable_if<
231
+ absl::conjunction<
232
+ absl::negation<std::is_same<T, U> >,
233
+ std::is_constructible<T, U&&>,
234
+ absl::negation<
235
+ optional_internal::
236
+ is_constructible_convertible_from_optional<T, U> >,
237
+ std::is_convertible<U&&, T> >::value,
238
+ bool>::type = false>
239
+ optional(optional<U>&& rhs) {
240
+ if (rhs) {
241
+ this->construct(std::move(*rhs));
242
+ }
243
+ }
244
+
245
+ // Converting move constructor (explicit)
246
+ template <
247
+ typename U,
248
+ typename std::enable_if<
249
+ absl::conjunction<
250
+ absl::negation<std::is_same<T, U>>, std::is_constructible<T, U&&>,
251
+ absl::negation<
252
+ optional_internal::is_constructible_convertible_from_optional<
253
+ T, U>>,
254
+ absl::negation<std::is_convertible<U&&, T>>>::value,
255
+ bool>::type = false>
256
+ explicit optional(optional<U>&& rhs) {
257
+ if (rhs) {
258
+ this->construct(std::move(*rhs));
259
+ }
260
+ }
261
+
262
+ // Destructor. Trivial if `T` is trivially destructible.
263
+ ~optional() = default;
264
+
265
+ // Assignment Operators
266
+
267
+ // Assignment from `nullopt`
268
+ //
269
+ // Example:
270
+ //
271
+ // struct S { int value; };
272
+ // optional<S> opt = absl::nullopt; // Could also use opt = { };
273
+ optional& operator=(nullopt_t) noexcept {
274
+ this->destruct();
275
+ return *this;
276
+ }
277
+
278
+ // Copy assignment operator, standard semantics
279
+ optional& operator=(const optional& src) = default;
280
+
281
+ // Move assignment operator, standard semantics
282
+ optional& operator=(optional&& src) = default;
283
+
284
+ // Value assignment operators
285
+ template <
286
+ typename U = T,
287
+ typename = typename std::enable_if<absl::conjunction<
288
+ absl::negation<
289
+ std::is_same<optional<T>, typename std::decay<U>::type>>,
290
+ absl::negation<
291
+ absl::conjunction<std::is_scalar<T>,
292
+ std::is_same<T, typename std::decay<U>::type>>>,
293
+ std::is_constructible<T, U>, std::is_assignable<T&, U>>::value>::type>
294
+ optional& operator=(U&& v) {
295
+ this->assign(std::forward<U>(v));
296
+ return *this;
297
+ }
298
+
299
+ template <
300
+ typename U,
301
+ typename = typename std::enable_if<absl::conjunction<
302
+ absl::negation<std::is_same<T, U>>,
303
+ std::is_constructible<T, const U&>, std::is_assignable<T&, const U&>,
304
+ absl::negation<
305
+ optional_internal::
306
+ is_constructible_convertible_assignable_from_optional<
307
+ T, U>>>::value>::type>
308
+ optional& operator=(const optional<U>& rhs) {
309
+ if (rhs) {
310
+ this->assign(*rhs);
311
+ } else {
312
+ this->destruct();
313
+ }
314
+ return *this;
315
+ }
316
+
317
+ template <typename U,
318
+ typename = typename std::enable_if<absl::conjunction<
319
+ absl::negation<std::is_same<T, U>>, std::is_constructible<T, U>,
320
+ std::is_assignable<T&, U>,
321
+ absl::negation<
322
+ optional_internal::
323
+ is_constructible_convertible_assignable_from_optional<
324
+ T, U>>>::value>::type>
325
+ optional& operator=(optional<U>&& rhs) {
326
+ if (rhs) {
327
+ this->assign(std::move(*rhs));
328
+ } else {
329
+ this->destruct();
330
+ }
331
+ return *this;
332
+ }
333
+
334
+ // Modifiers
335
+
336
+ // optional::reset()
337
+ //
338
+ // Destroys the inner `T` value of an `absl::optional` if one is present.
339
+ ABSL_ATTRIBUTE_REINITIALIZES void reset() noexcept { this->destruct(); }
340
+
341
+ // optional::emplace()
342
+ //
343
+ // (Re)constructs the underlying `T` in-place with the given forwarded
344
+ // arguments.
345
+ //
346
+ // Example:
347
+ //
348
+ // optional<Foo> opt;
349
+ // opt.emplace(arg1,arg2,arg3); // Constructs Foo(arg1,arg2,arg3)
350
+ //
351
+ // If the optional is non-empty, and the `args` refer to subobjects of the
352
+ // current object, then behaviour is undefined, because the current object
353
+ // will be destructed before the new object is constructed with `args`.
354
+ template <typename... Args,
355
+ typename = typename std::enable_if<
356
+ std::is_constructible<T, Args&&...>::value>::type>
357
+ T& emplace(Args&&... args) {
358
+ this->destruct();
359
+ this->construct(std::forward<Args>(args)...);
360
+ return reference();
361
+ }
362
+
363
+ // Emplace reconstruction overload for an initializer list and the given
364
+ // forwarded arguments.
365
+ //
366
+ // Example:
367
+ //
368
+ // struct Foo {
369
+ // Foo(std::initializer_list<int>);
370
+ // };
371
+ //
372
+ // optional<Foo> opt;
373
+ // opt.emplace({1,2,3}); // Constructs Foo({1,2,3})
374
+ template <typename U, typename... Args,
375
+ typename = typename std::enable_if<std::is_constructible<
376
+ T, std::initializer_list<U>&, Args&&...>::value>::type>
377
+ T& emplace(std::initializer_list<U> il, Args&&... args) {
378
+ this->destruct();
379
+ this->construct(il, std::forward<Args>(args)...);
380
+ return reference();
381
+ }
382
+
383
+ // Swaps
384
+
385
+ // Swap, standard semantics
386
+ void swap(optional& rhs) noexcept(
387
+ std::is_nothrow_move_constructible<T>::value&&
388
+ type_traits_internal::IsNothrowSwappable<T>::value) {
389
+ if (*this) {
390
+ if (rhs) {
391
+ type_traits_internal::Swap(**this, *rhs);
392
+ } else {
393
+ rhs.construct(std::move(**this));
394
+ this->destruct();
395
+ }
396
+ } else {
397
+ if (rhs) {
398
+ this->construct(std::move(*rhs));
399
+ rhs.destruct();
400
+ } else {
401
+ // No effect (swap(disengaged, disengaged)).
402
+ }
403
+ }
404
+ }
405
+
406
+ // Observers
407
+
408
+ // optional::operator->()
409
+ //
410
+ // Accesses the underlying `T` value's member `m` of an `optional`. If the
411
+ // `optional` is empty, behavior is undefined.
412
+ //
413
+ // If you need myOpt->foo in constexpr, use (*myOpt).foo instead.
414
+ const T* operator->() const {
415
+ assert(this->engaged_);
416
+ return std::addressof(this->data_);
417
+ }
418
+ T* operator->() {
419
+ assert(this->engaged_);
420
+ return std::addressof(this->data_);
421
+ }
422
+
423
+ // optional::operator*()
424
+ //
425
+ // Accesses the underlying `T` value of an `optional`. If the `optional` is
426
+ // empty, behavior is undefined.
427
+ constexpr const T& operator*() const& {
428
+ return ABSL_ASSERT(this->engaged_), reference();
429
+ }
430
+ T& operator*() & {
431
+ assert(this->engaged_);
432
+ return reference();
433
+ }
434
+ constexpr const T&& operator*() const && {
435
+ return absl::move(reference());
436
+ }
437
+ T&& operator*() && {
438
+ assert(this->engaged_);
439
+ return std::move(reference());
440
+ }
441
+
442
+ // optional::operator bool()
443
+ //
444
+ // Returns false if and only if the `optional` is empty.
445
+ //
446
+ // if (opt) {
447
+ // // do something with opt.value();
448
+ // } else {
449
+ // // opt is empty.
450
+ // }
451
+ //
452
+ constexpr explicit operator bool() const noexcept { return this->engaged_; }
453
+
454
+ // optional::has_value()
455
+ //
456
+ // Determines whether the `optional` contains a value. Returns `false` if and
457
+ // only if `*this` is empty.
458
+ constexpr bool has_value() const noexcept { return this->engaged_; }
459
+
460
+ // Suppress bogus warning on MSVC: MSVC complains call to reference() after
461
+ // throw_bad_optional_access() is unreachable.
462
+ #ifdef _MSC_VER
463
+ #pragma warning(push)
464
+ #pragma warning(disable : 4702)
465
+ #endif // _MSC_VER
466
+ // optional::value()
467
+ //
468
+ // Returns a reference to an `optional`s underlying value. The constness
469
+ // and lvalue/rvalue-ness of the `optional` is preserved to the view of
470
+ // the `T` sub-object. Throws `absl::bad_optional_access` when the `optional`
471
+ // is empty.
472
+ constexpr const T& value() const & {
473
+ return static_cast<bool>(*this)
474
+ ? reference()
475
+ : (optional_internal::throw_bad_optional_access(), reference());
476
+ }
477
+ T& value() & {
478
+ return static_cast<bool>(*this)
479
+ ? reference()
480
+ : (optional_internal::throw_bad_optional_access(), reference());
481
+ }
482
+ T&& value() && { // NOLINT(build/c++11)
483
+ return std::move(
484
+ static_cast<bool>(*this)
485
+ ? reference()
486
+ : (optional_internal::throw_bad_optional_access(), reference()));
487
+ }
488
+ constexpr const T&& value() const && { // NOLINT(build/c++11)
489
+ return absl::move(
490
+ static_cast<bool>(*this)
491
+ ? reference()
492
+ : (optional_internal::throw_bad_optional_access(), reference()));
493
+ }
494
+ #ifdef _MSC_VER
495
+ #pragma warning(pop)
496
+ #endif // _MSC_VER
497
+
498
+ // optional::value_or()
499
+ //
500
+ // Returns either the value of `T` or a passed default `v` if the `optional`
501
+ // is empty.
502
+ template <typename U>
503
+ constexpr T value_or(U&& v) const& {
504
+ static_assert(std::is_copy_constructible<value_type>::value,
505
+ "optional<T>::value_or: T must be copy constructible");
506
+ static_assert(std::is_convertible<U&&, value_type>::value,
507
+ "optional<T>::value_or: U must be convertible to T");
508
+ return static_cast<bool>(*this)
509
+ ? **this
510
+ : static_cast<T>(absl::forward<U>(v));
511
+ }
512
+ template <typename U>
513
+ T value_or(U&& v) && { // NOLINT(build/c++11)
514
+ static_assert(std::is_move_constructible<value_type>::value,
515
+ "optional<T>::value_or: T must be move constructible");
516
+ static_assert(std::is_convertible<U&&, value_type>::value,
517
+ "optional<T>::value_or: U must be convertible to T");
518
+ return static_cast<bool>(*this) ? std::move(**this)
519
+ : static_cast<T>(std::forward<U>(v));
520
+ }
521
+
522
+ private:
523
+ // Private accessors for internal storage viewed as reference to T.
524
+ constexpr const T& reference() const { return this->data_; }
525
+ T& reference() { return this->data_; }
526
+
527
+ // T constraint checks. You can't have an optional of nullopt_t, in_place_t
528
+ // or a reference.
529
+ static_assert(
530
+ !std::is_same<nullopt_t, typename std::remove_cv<T>::type>::value,
531
+ "optional<nullopt_t> is not allowed.");
532
+ static_assert(
533
+ !std::is_same<in_place_t, typename std::remove_cv<T>::type>::value,
534
+ "optional<in_place_t> is not allowed.");
535
+ static_assert(!std::is_reference<T>::value,
536
+ "optional<reference> is not allowed.");
537
+ };
538
+
539
+ // Non-member functions
540
+
541
+ // swap()
542
+ //
543
+ // Performs a swap between two `absl::optional` objects, using standard
544
+ // semantics.
545
+ template <typename T, typename std::enable_if<
546
+ std::is_move_constructible<T>::value &&
547
+ type_traits_internal::IsSwappable<T>::value,
548
+ bool>::type = false>
549
+ void swap(optional<T>& a, optional<T>& b) noexcept(noexcept(a.swap(b))) {
550
+ a.swap(b);
551
+ }
552
+
553
+ // make_optional()
554
+ //
555
+ // Creates a non-empty `optional<T>` where the type of `T` is deduced. An
556
+ // `absl::optional` can also be explicitly instantiated with
557
+ // `make_optional<T>(v)`.
558
+ //
559
+ // Note: `make_optional()` constructions may be declared `constexpr` for
560
+ // trivially copyable types `T`. Non-trivial types require copy elision
561
+ // support in C++17 for `make_optional` to support `constexpr` on such
562
+ // non-trivial types.
563
+ //
564
+ // Example:
565
+ //
566
+ // constexpr absl::optional<int> opt = absl::make_optional(1);
567
+ // static_assert(opt.value() == 1, "");
568
+ template <typename T>
569
+ constexpr optional<typename std::decay<T>::type> make_optional(T&& v) {
570
+ return optional<typename std::decay<T>::type>(absl::forward<T>(v));
571
+ }
572
+
573
+ template <typename T, typename... Args>
574
+ constexpr optional<T> make_optional(Args&&... args) {
575
+ return optional<T>(in_place_t(), absl::forward<Args>(args)...);
576
+ }
577
+
578
+ template <typename T, typename U, typename... Args>
579
+ constexpr optional<T> make_optional(std::initializer_list<U> il,
580
+ Args&&... args) {
581
+ return optional<T>(in_place_t(), il,
582
+ absl::forward<Args>(args)...);
583
+ }
584
+
585
+ // Relational operators [optional.relops]
586
+
587
+ // Empty optionals are considered equal to each other and less than non-empty
588
+ // optionals. Supports relations between optional<T> and optional<U>, between
589
+ // optional<T> and U, and between optional<T> and nullopt.
590
+ //
591
+ // Note: We're careful to support T having non-bool relationals.
592
+
593
+ // Requires: The expression, e.g. "*x == *y" shall be well-formed and its result
594
+ // shall be convertible to bool.
595
+ // The C++17 (N4606) "Returns:" statements are translated into
596
+ // code in an obvious way here, and the original text retained as function docs.
597
+ // Returns: If bool(x) != bool(y), false; otherwise if bool(x) == false, true;
598
+ // otherwise *x == *y.
599
+ template <typename T, typename U>
600
+ constexpr auto operator==(const optional<T>& x, const optional<U>& y)
601
+ -> decltype(optional_internal::convertible_to_bool(*x == *y)) {
602
+ return static_cast<bool>(x) != static_cast<bool>(y)
603
+ ? false
604
+ : static_cast<bool>(x) == false ? true
605
+ : static_cast<bool>(*x == *y);
606
+ }
607
+
608
+ // Returns: If bool(x) != bool(y), true; otherwise, if bool(x) == false, false;
609
+ // otherwise *x != *y.
610
+ template <typename T, typename U>
611
+ constexpr auto operator!=(const optional<T>& x, const optional<U>& y)
612
+ -> decltype(optional_internal::convertible_to_bool(*x != *y)) {
613
+ return static_cast<bool>(x) != static_cast<bool>(y)
614
+ ? true
615
+ : static_cast<bool>(x) == false ? false
616
+ : static_cast<bool>(*x != *y);
617
+ }
618
+ // Returns: If !y, false; otherwise, if !x, true; otherwise *x < *y.
619
+ template <typename T, typename U>
620
+ constexpr auto operator<(const optional<T>& x, const optional<U>& y)
621
+ -> decltype(optional_internal::convertible_to_bool(*x < *y)) {
622
+ return !y ? false : !x ? true : static_cast<bool>(*x < *y);
623
+ }
624
+ // Returns: If !x, false; otherwise, if !y, true; otherwise *x > *y.
625
+ template <typename T, typename U>
626
+ constexpr auto operator>(const optional<T>& x, const optional<U>& y)
627
+ -> decltype(optional_internal::convertible_to_bool(*x > *y)) {
628
+ return !x ? false : !y ? true : static_cast<bool>(*x > *y);
629
+ }
630
+ // Returns: If !x, true; otherwise, if !y, false; otherwise *x <= *y.
631
+ template <typename T, typename U>
632
+ constexpr auto operator<=(const optional<T>& x, const optional<U>& y)
633
+ -> decltype(optional_internal::convertible_to_bool(*x <= *y)) {
634
+ return !x ? true : !y ? false : static_cast<bool>(*x <= *y);
635
+ }
636
+ // Returns: If !y, true; otherwise, if !x, false; otherwise *x >= *y.
637
+ template <typename T, typename U>
638
+ constexpr auto operator>=(const optional<T>& x, const optional<U>& y)
639
+ -> decltype(optional_internal::convertible_to_bool(*x >= *y)) {
640
+ return !y ? true : !x ? false : static_cast<bool>(*x >= *y);
641
+ }
642
+
643
+ // Comparison with nullopt [optional.nullops]
644
+ // The C++17 (N4606) "Returns:" statements are used directly here.
645
+ template <typename T>
646
+ constexpr bool operator==(const optional<T>& x, nullopt_t) noexcept {
647
+ return !x;
648
+ }
649
+ template <typename T>
650
+ constexpr bool operator==(nullopt_t, const optional<T>& x) noexcept {
651
+ return !x;
652
+ }
653
+ template <typename T>
654
+ constexpr bool operator!=(const optional<T>& x, nullopt_t) noexcept {
655
+ return static_cast<bool>(x);
656
+ }
657
+ template <typename T>
658
+ constexpr bool operator!=(nullopt_t, const optional<T>& x) noexcept {
659
+ return static_cast<bool>(x);
660
+ }
661
+ template <typename T>
662
+ constexpr bool operator<(const optional<T>&, nullopt_t) noexcept {
663
+ return false;
664
+ }
665
+ template <typename T>
666
+ constexpr bool operator<(nullopt_t, const optional<T>& x) noexcept {
667
+ return static_cast<bool>(x);
668
+ }
669
+ template <typename T>
670
+ constexpr bool operator<=(const optional<T>& x, nullopt_t) noexcept {
671
+ return !x;
672
+ }
673
+ template <typename T>
674
+ constexpr bool operator<=(nullopt_t, const optional<T>&) noexcept {
675
+ return true;
676
+ }
677
+ template <typename T>
678
+ constexpr bool operator>(const optional<T>& x, nullopt_t) noexcept {
679
+ return static_cast<bool>(x);
680
+ }
681
+ template <typename T>
682
+ constexpr bool operator>(nullopt_t, const optional<T>&) noexcept {
683
+ return false;
684
+ }
685
+ template <typename T>
686
+ constexpr bool operator>=(const optional<T>&, nullopt_t) noexcept {
687
+ return true;
688
+ }
689
+ template <typename T>
690
+ constexpr bool operator>=(nullopt_t, const optional<T>& x) noexcept {
691
+ return !x;
692
+ }
693
+
694
+ // Comparison with T [optional.comp_with_t]
695
+
696
+ // Requires: The expression, e.g. "*x == v" shall be well-formed and its result
697
+ // shall be convertible to bool.
698
+ // The C++17 (N4606) "Equivalent to:" statements are used directly here.
699
+ template <typename T, typename U>
700
+ constexpr auto operator==(const optional<T>& x, const U& v)
701
+ -> decltype(optional_internal::convertible_to_bool(*x == v)) {
702
+ return static_cast<bool>(x) ? static_cast<bool>(*x == v) : false;
703
+ }
704
+ template <typename T, typename U>
705
+ constexpr auto operator==(const U& v, const optional<T>& x)
706
+ -> decltype(optional_internal::convertible_to_bool(v == *x)) {
707
+ return static_cast<bool>(x) ? static_cast<bool>(v == *x) : false;
708
+ }
709
+ template <typename T, typename U>
710
+ constexpr auto operator!=(const optional<T>& x, const U& v)
711
+ -> decltype(optional_internal::convertible_to_bool(*x != v)) {
712
+ return static_cast<bool>(x) ? static_cast<bool>(*x != v) : true;
713
+ }
714
+ template <typename T, typename U>
715
+ constexpr auto operator!=(const U& v, const optional<T>& x)
716
+ -> decltype(optional_internal::convertible_to_bool(v != *x)) {
717
+ return static_cast<bool>(x) ? static_cast<bool>(v != *x) : true;
718
+ }
719
+ template <typename T, typename U>
720
+ constexpr auto operator<(const optional<T>& x, const U& v)
721
+ -> decltype(optional_internal::convertible_to_bool(*x < v)) {
722
+ return static_cast<bool>(x) ? static_cast<bool>(*x < v) : true;
723
+ }
724
+ template <typename T, typename U>
725
+ constexpr auto operator<(const U& v, const optional<T>& x)
726
+ -> decltype(optional_internal::convertible_to_bool(v < *x)) {
727
+ return static_cast<bool>(x) ? static_cast<bool>(v < *x) : false;
728
+ }
729
+ template <typename T, typename U>
730
+ constexpr auto operator<=(const optional<T>& x, const U& v)
731
+ -> decltype(optional_internal::convertible_to_bool(*x <= v)) {
732
+ return static_cast<bool>(x) ? static_cast<bool>(*x <= v) : true;
733
+ }
734
+ template <typename T, typename U>
735
+ constexpr auto operator<=(const U& v, const optional<T>& x)
736
+ -> decltype(optional_internal::convertible_to_bool(v <= *x)) {
737
+ return static_cast<bool>(x) ? static_cast<bool>(v <= *x) : false;
738
+ }
739
+ template <typename T, typename U>
740
+ constexpr auto operator>(const optional<T>& x, const U& v)
741
+ -> decltype(optional_internal::convertible_to_bool(*x > v)) {
742
+ return static_cast<bool>(x) ? static_cast<bool>(*x > v) : false;
743
+ }
744
+ template <typename T, typename U>
745
+ constexpr auto operator>(const U& v, const optional<T>& x)
746
+ -> decltype(optional_internal::convertible_to_bool(v > *x)) {
747
+ return static_cast<bool>(x) ? static_cast<bool>(v > *x) : true;
748
+ }
749
+ template <typename T, typename U>
750
+ constexpr auto operator>=(const optional<T>& x, const U& v)
751
+ -> decltype(optional_internal::convertible_to_bool(*x >= v)) {
752
+ return static_cast<bool>(x) ? static_cast<bool>(*x >= v) : false;
753
+ }
754
+ template <typename T, typename U>
755
+ constexpr auto operator>=(const U& v, const optional<T>& x)
756
+ -> decltype(optional_internal::convertible_to_bool(v >= *x)) {
757
+ return static_cast<bool>(x) ? static_cast<bool>(v >= *x) : true;
758
+ }
759
+
760
+ ABSL_NAMESPACE_END
761
+ } // namespace absl
762
+
763
+ namespace std {
764
+
765
+ // std::hash specialization for absl::optional.
766
+ template <typename T>
767
+ struct hash<absl::optional<T> >
768
+ : absl::optional_internal::optional_hash_base<T> {};
769
+
770
+ } // namespace std
771
+
772
+ #undef ABSL_MSVC_CONSTEXPR_BUG_IN_UNION_LIKE_CLASS
773
+
774
+ #endif // ABSL_USES_STD_OPTIONAL
775
+
776
+ #endif // ABSL_TYPES_OPTIONAL_H_