Coverage Report

Created: 2024-11-18 11:49

/root/doris/be/src/util/expected.hpp
Line
Count
Source (jump to first uncovered line)
1
// Licensed to the Apache Software Foundation (ASF) under one
2
// or more contributor license agreements.  See the NOTICE file
3
// distributed with this work for additional information
4
// regarding copyright ownership.  The ASF licenses this file
5
// to you under the Apache License, Version 2.0 (the
6
// "License"); you may not use this file except in compliance
7
// with the License.  You may obtain a copy of the License at
8
//
9
//   http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing,
12
// software distributed under the License is distributed on an
13
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
// KIND, either express or implied.  See the License for the
15
// specific language governing permissions and limitations
16
// under the License.
17
18
//the code refer: https://github.com/TartanLlama/expected/blob/master/include/tl/expected.hpp
19
///
20
// expected - An implementation of std::expected with extensions
21
// Written in 2017 by Sy Brand (tartanllama@gmail.com, @TartanLlama)
22
//
23
// Documentation available at http://tl.tartanllama.xyz/
24
//
25
// To the extent possible under law, the author(s) have dedicated all
26
// copyright and related and neighboring rights to this software to the
27
// public domain worldwide. This software is distributed without any warranty.
28
//
29
// You should have received a copy of the CC0 Public Domain Dedication
30
// along with this software. If not, see
31
// <http://creativecommons.org/publicdomain/zero/1.0/>.
32
///
33
34
// clang-format off
35
// NOLINTBEGIN
36
#ifndef TL_EXPECTED_HPP
37
#define TL_EXPECTED_HPP
38
39
#define TL_EXPECTED_VERSION_MAJOR 1
40
#define TL_EXPECTED_VERSION_MINOR 1
41
#define TL_EXPECTED_VERSION_PATCH 0
42
43
#include <exception>
44
#include <functional>
45
#include <type_traits>
46
#include <utility>
47
48
#if defined(__EXCEPTIONS) || defined(_CPPUNWIND)
49
#define TL_EXPECTED_EXCEPTIONS_ENABLED
50
#endif
51
52
#if (defined(_MSC_VER) && _MSC_VER == 1900)
53
#define TL_EXPECTED_MSVC2015
54
#define TL_EXPECTED_MSVC2015_CONSTEXPR
55
#else
56
#define TL_EXPECTED_MSVC2015_CONSTEXPR constexpr
57
#endif
58
59
#if (defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ <= 9 &&              \
60
     !defined(__clang__))
61
#define TL_EXPECTED_GCC49
62
#endif
63
64
#if (defined(__GNUC__) && __GNUC__ == 5 && __GNUC_MINOR__ <= 4 &&              \
65
     !defined(__clang__))
66
#define TL_EXPECTED_GCC54
67
#endif
68
69
#if (defined(__GNUC__) && __GNUC__ == 5 && __GNUC_MINOR__ <= 5 &&              \
70
     !defined(__clang__))
71
#define TL_EXPECTED_GCC55
72
#endif
73
74
#if !defined(TL_ASSERT)
75
//can't have assert in constexpr in C++11 and GCC 4.9 has a compiler bug
76
#if (__cplusplus > 201103L) && !defined(TL_EXPECTED_GCC49)
77
#include <cassert>
78
4
#define TL_ASSERT(x) assert(x)
79
#else 
80
#define TL_ASSERT(x)
81
#endif
82
#endif
83
84
#if (defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ <= 9 &&              \
85
     !defined(__clang__))
86
// GCC < 5 doesn't support overloading on const&& for member functions
87
88
#define TL_EXPECTED_NO_CONSTRR
89
// GCC < 5 doesn't support some standard C++11 type traits
90
#define TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T)                         \
91
  std::has_trivial_copy_constructor<T>
92
#define TL_EXPECTED_IS_TRIVIALLY_COPY_ASSIGNABLE(T)                            \
93
  std::has_trivial_copy_assign<T>
94
95
// This one will be different for GCC 5.7 if it's ever supported
96
#define TL_EXPECTED_IS_TRIVIALLY_DESTRUCTIBLE(T)                               \
97
  std::is_trivially_destructible<T>
98
99
// GCC 5 < v < 8 has a bug in is_trivially_copy_constructible which breaks
100
// std::vector for non-copyable types
101
#elif (defined(__GNUC__) && __GNUC__ < 8 && !defined(__clang__))
102
#ifndef TL_GCC_LESS_8_TRIVIALLY_COPY_CONSTRUCTIBLE_MUTEX
103
#define TL_GCC_LESS_8_TRIVIALLY_COPY_CONSTRUCTIBLE_MUTEX
104
namespace tl {
105
namespace detail {
106
template <class T>
107
struct is_trivially_copy_constructible
108
    : std::is_trivially_copy_constructible<T> {};
109
#ifdef _GLIBCXX_VECTOR
110
template <class T, class A>
111
struct is_trivially_copy_constructible<std::vector<T, A>> : std::false_type {};
112
#endif
113
} // namespace detail
114
} // namespace tl
115
#endif
116
117
#define TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T)                         \
118
  tl::detail::is_trivially_copy_constructible<T>
119
#define TL_EXPECTED_IS_TRIVIALLY_COPY_ASSIGNABLE(T)                            \
120
  std::is_trivially_copy_assignable<T>
121
#define TL_EXPECTED_IS_TRIVIALLY_DESTRUCTIBLE(T)                               \
122
  std::is_trivially_destructible<T>
123
#else
124
#define TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T)                         \
125
  std::is_trivially_copy_constructible<T>
126
#define TL_EXPECTED_IS_TRIVIALLY_COPY_ASSIGNABLE(T)                            \
127
  std::is_trivially_copy_assignable<T>
128
#define TL_EXPECTED_IS_TRIVIALLY_DESTRUCTIBLE(T)                               \
129
  std::is_trivially_destructible<T>
130
#endif
131
132
#if __cplusplus > 201103L
133
#define TL_EXPECTED_CXX14
134
#endif
135
136
#ifdef TL_EXPECTED_GCC49
137
#define TL_EXPECTED_GCC49_CONSTEXPR
138
#else
139
#define TL_EXPECTED_GCC49_CONSTEXPR constexpr
140
#endif
141
142
#if (__cplusplus == 201103L || defined(TL_EXPECTED_MSVC2015) ||                \
143
     defined(TL_EXPECTED_GCC49))
144
#define TL_EXPECTED_11_CONSTEXPR
145
#else
146
#define TL_EXPECTED_11_CONSTEXPR constexpr
147
#endif
148
149
namespace tl {
150
template <class T, class E> class expected;
151
152
#ifndef TL_MONOSTATE_INPLACE_MUTEX
153
#define TL_MONOSTATE_INPLACE_MUTEX
154
class monostate {};
155
156
struct in_place_t {
157
  explicit in_place_t() = default;
158
};
159
static constexpr in_place_t in_place{};
160
#endif
161
162
template <class E> class unexpected {
163
public:
164
  static_assert(!std::is_same<E, void>::value, "E must not be void");
165
166
  unexpected() = delete;
167
  constexpr explicit unexpected(const E &e) : m_val(e) {}
168
169
20
  constexpr explicit unexpected(E &&e) : m_val(std::move(e)) {}
170
171
  template <class... Args, typename std::enable_if<std::is_constructible<
172
                               E, Args &&...>::value>::type * = nullptr>
173
  constexpr explicit unexpected(Args &&...args)
174
      : m_val(std::forward<Args>(args)...) {}
175
  template <
176
      class U, class... Args,
177
      typename std::enable_if<std::is_constructible<
178
          E, std::initializer_list<U> &, Args &&...>::value>::type * = nullptr>
179
  constexpr explicit unexpected(std::initializer_list<U> l, Args &&...args)
180
      : m_val(l, std::forward<Args>(args)...) {}
181
182
0
  constexpr const E &value() const & { return m_val; }
183
17
  TL_EXPECTED_11_CONSTEXPR E &value() & { return m_val; }
184
0
  TL_EXPECTED_11_CONSTEXPR E &&value() && { return std::move(m_val); }
185
  constexpr const E &&value() const && { return std::move(m_val); }
186
187
private:
188
  E m_val;
189
};
190
191
#ifdef __cpp_deduction_guides
192
template <class E> unexpected(E) -> unexpected<E>;
193
#endif
194
195
template <class E>
196
constexpr bool operator==(const unexpected<E> &lhs, const unexpected<E> &rhs) {
197
  return lhs.value() == rhs.value();
198
}
199
template <class E>
200
constexpr auto operator<=>(const unexpected<E> &lhs, const unexpected<E> &rhs) {
201
  return lhs.value() <=> rhs.value();
202
}
203
204
template <class E>
205
unexpected<typename std::decay<E>::type> make_unexpected(E &&e) {
206
  return unexpected<typename std::decay<E>::type>(std::forward<E>(e));
207
}
208
209
struct unexpect_t {
210
  unexpect_t() = default;
211
};
212
static constexpr unexpect_t unexpect{};
213
214
namespace detail {
215
template <typename E>
216
0
[[noreturn]] TL_EXPECTED_11_CONSTEXPR void throw_exception(E &&e) {
217
0
#ifdef TL_EXPECTED_EXCEPTIONS_ENABLED
218
0
  throw std::forward<E>(e);
219
#else
220
  (void)e;
221
#ifdef _MSC_VER
222
  __assume(0);
223
#else
224
 LOG(FATAL) << "__builtin_unreachable";
225
  __builtin_unreachable();
226
#endif
227
#endif
228
0
}
229
230
#ifndef TL_TRAITS_MUTEX
231
#define TL_TRAITS_MUTEX
232
// C++14-style aliases for brevity
233
template <class T> using remove_const_t = typename std::remove_const<T>::type;
234
template <class T>
235
using remove_reference_t = typename std::remove_reference<T>::type;
236
template <class T> using decay_t = typename std::decay<T>::type;
237
template <bool E, class T = void>
238
using enable_if_t = typename std::enable_if<E, T>::type;
239
template <bool B, class T, class F>
240
using conditional_t = typename std::conditional<B, T, F>::type;
241
242
// std::conjunction from C++17
243
template <class...> struct conjunction : std::true_type {};
244
template <class B> struct conjunction<B> : B {};
245
template <class B, class... Bs>
246
struct conjunction<B, Bs...>
247
    : std::conditional<bool(B::value), conjunction<Bs...>, B>::type {};
248
249
#if defined(_LIBCPP_VERSION) && __cplusplus == 201103L
250
#define TL_TRAITS_LIBCXX_MEM_FN_WORKAROUND
251
#endif
252
253
// In C++11 mode, there's an issue in libc++'s std::mem_fn
254
// which results in a hard-error when using it in a noexcept expression
255
// in some cases. This is a check to workaround the common failing case.
256
#ifdef TL_TRAITS_LIBCXX_MEM_FN_WORKAROUND
257
template <class T>
258
struct is_pointer_to_non_const_member_func : std::false_type {};
259
template <class T, class Ret, class... Args>
260
struct is_pointer_to_non_const_member_func<Ret (T::*)(Args...)>
261
    : std::true_type {};
262
template <class T, class Ret, class... Args>
263
struct is_pointer_to_non_const_member_func<Ret (T::*)(Args...) &>
264
    : std::true_type {};
265
template <class T, class Ret, class... Args>
266
struct is_pointer_to_non_const_member_func<Ret (T::*)(Args...) &&>
267
    : std::true_type {};
268
template <class T, class Ret, class... Args>
269
struct is_pointer_to_non_const_member_func<Ret (T::*)(Args...) volatile>
270
    : std::true_type {};
271
template <class T, class Ret, class... Args>
272
struct is_pointer_to_non_const_member_func<Ret (T::*)(Args...) volatile &>
273
    : std::true_type {};
274
template <class T, class Ret, class... Args>
275
struct is_pointer_to_non_const_member_func<Ret (T::*)(Args...) volatile &&>
276
    : std::true_type {};
277
278
template <class T> struct is_const_or_const_ref : std::false_type {};
279
template <class T> struct is_const_or_const_ref<T const &> : std::true_type {};
280
template <class T> struct is_const_or_const_ref<T const> : std::true_type {};
281
#endif
282
283
// std::invoke from C++17
284
// https://stackoverflow.com/questions/38288042/c11-14-invoke-workaround
285
template <
286
    typename Fn, typename... Args,
287
#ifdef TL_TRAITS_LIBCXX_MEM_FN_WORKAROUND
288
    typename = enable_if_t<!(is_pointer_to_non_const_member_func<Fn>::value &&
289
                             is_const_or_const_ref<Args...>::value)>,
290
#endif
291
    typename = enable_if_t<std::is_member_pointer<decay_t<Fn>>::value>, int = 0>
292
constexpr auto invoke(Fn &&f, Args &&...args) noexcept(
293
    noexcept(std::mem_fn(f)(std::forward<Args>(args)...)))
294
    -> decltype(std::mem_fn(f)(std::forward<Args>(args)...)) {
295
  return std::mem_fn(f)(std::forward<Args>(args)...);
296
}
297
298
template <typename Fn, typename... Args,
299
          typename = enable_if_t<!std::is_member_pointer<decay_t<Fn>>::value>>
300
constexpr auto invoke(Fn &&f, Args &&...args) noexcept(
301
    noexcept(std::forward<Fn>(f)(std::forward<Args>(args)...)))
302
    -> decltype(std::forward<Fn>(f)(std::forward<Args>(args)...)) {
303
  return std::forward<Fn>(f)(std::forward<Args>(args)...);
304
}
305
306
// std::invoke_result from C++17
307
template <class F, class, class... Us> struct invoke_result_impl;
308
309
template <class F, class... Us>
310
struct invoke_result_impl<
311
    F,
312
    decltype(detail::invoke(std::declval<F>(), std::declval<Us>()...), void()),
313
    Us...> {
314
  using type =
315
      decltype(detail::invoke(std::declval<F>(), std::declval<Us>()...));
316
};
317
318
template <class F, class... Us>
319
using invoke_result = invoke_result_impl<F, void, Us...>;
320
321
template <class F, class... Us>
322
using invoke_result_t = typename invoke_result<F, Us...>::type;
323
324
#if defined(_MSC_VER) && _MSC_VER <= 1900
325
// TODO make a version which works with MSVC 2015
326
template <class T, class U = T> struct is_swappable : std::true_type {};
327
328
template <class T, class U = T> struct is_nothrow_swappable : std::true_type {};
329
#else
330
// https://stackoverflow.com/questions/26744589/what-is-a-proper-way-to-implement-is-swappable-to-test-for-the-swappable-concept
331
namespace swap_adl_tests {
332
// if swap ADL finds this then it would call std::swap otherwise (same
333
// signature)
334
struct tag {};
335
336
template <class T> tag swap(T &, T &);
337
template <class T, std::size_t N> tag swap(T (&a)[N], T (&b)[N]);
338
339
// helper functions to test if an unqualified swap is possible, and if it
340
// becomes std::swap
341
template <class, class> std::false_type can_swap(...) noexcept(false);
342
template <class T, class U,
343
          class = decltype(swap(std::declval<T &>(), std::declval<U &>()))>
344
std::true_type can_swap(int) noexcept(noexcept(swap(std::declval<T &>(),
345
                                                    std::declval<U &>())));
346
347
template <class, class> std::false_type uses_std(...);
348
template <class T, class U>
349
std::is_same<decltype(swap(std::declval<T &>(), std::declval<U &>())), tag>
350
uses_std(int);
351
352
template <class T>
353
struct is_std_swap_noexcept
354
    : std::integral_constant<bool,
355
                             std::is_nothrow_move_constructible<T>::value &&
356
                                 std::is_nothrow_move_assignable<T>::value> {};
357
358
template <class T, std::size_t N>
359
struct is_std_swap_noexcept<T[N]> : is_std_swap_noexcept<T> {};
360
361
template <class T, class U>
362
struct is_adl_swap_noexcept
363
    : std::integral_constant<bool, noexcept(can_swap<T, U>(0))> {};
364
} // namespace swap_adl_tests
365
366
template <class T, class U = T>
367
struct is_swappable
368
    : std::integral_constant<
369
          bool,
370
          decltype(detail::swap_adl_tests::can_swap<T, U>(0))::value &&
371
              (!decltype(detail::swap_adl_tests::uses_std<T, U>(0))::value ||
372
               (std::is_move_assignable<T>::value &&
373
                std::is_move_constructible<T>::value))> {};
374
375
template <class T, std::size_t N>
376
struct is_swappable<T[N], T[N]>
377
    : std::integral_constant<
378
          bool,
379
          decltype(detail::swap_adl_tests::can_swap<T[N], T[N]>(0))::value &&
380
              (!decltype(detail::swap_adl_tests::uses_std<T[N], T[N]>(
381
                   0))::value ||
382
               is_swappable<T, T>::value)> {};
383
384
template <class T, class U = T>
385
struct is_nothrow_swappable
386
    : std::integral_constant<
387
          bool,
388
          is_swappable<T, U>::value &&
389
              ((decltype(detail::swap_adl_tests::uses_std<T, U>(0))::value &&
390
                detail::swap_adl_tests::is_std_swap_noexcept<T>::value) ||
391
               (!decltype(detail::swap_adl_tests::uses_std<T, U>(0))::value &&
392
                detail::swap_adl_tests::is_adl_swap_noexcept<T, U>::value))> {};
393
#endif
394
#endif
395
396
// Trait for checking if a type is a tl::expected
397
template <class T> struct is_expected_impl : std::false_type {};
398
template <class T, class E>
399
struct is_expected_impl<expected<T, E>> : std::true_type {};
400
template <class T> using is_expected = is_expected_impl<decay_t<T>>;
401
402
template <class T, class E, class U>
403
using expected_enable_forward_value = detail::enable_if_t<
404
    std::is_constructible<T, U &&>::value &&
405
    !std::is_same<detail::decay_t<U>, in_place_t>::value &&
406
    !std::is_same<expected<T, E>, detail::decay_t<U>>::value &&
407
    !std::is_same<unexpected<E>, detail::decay_t<U>>::value>;
408
409
template <class T, class E, class U, class G, class UR, class GR>
410
using expected_enable_from_other = detail::enable_if_t<
411
    std::is_constructible<T, UR>::value &&
412
    std::is_constructible<E, GR>::value &&
413
    !std::is_constructible<T, expected<U, G> &>::value &&
414
    !std::is_constructible<T, expected<U, G> &&>::value &&
415
    !std::is_constructible<T, const expected<U, G> &>::value &&
416
    !std::is_constructible<T, const expected<U, G> &&>::value &&
417
    !std::is_convertible<expected<U, G> &, T>::value &&
418
    !std::is_convertible<expected<U, G> &&, T>::value &&
419
    !std::is_convertible<const expected<U, G> &, T>::value &&
420
    !std::is_convertible<const expected<U, G> &&, T>::value>;
421
422
template <class T, class U>
423
using is_void_or = conditional_t<std::is_void<T>::value, std::true_type, U>;
424
425
template <class T>
426
using is_copy_constructible_or_void =
427
    is_void_or<T, std::is_copy_constructible<T>>;
428
429
template <class T>
430
using is_move_constructible_or_void =
431
    is_void_or<T, std::is_move_constructible<T>>;
432
433
template <class T>
434
using is_copy_assignable_or_void = is_void_or<T, std::is_copy_assignable<T>>;
435
436
template <class T>
437
using is_move_assignable_or_void = is_void_or<T, std::is_move_assignable<T>>;
438
439
} // namespace detail
440
441
namespace detail {
442
struct no_init_t {};
443
static constexpr no_init_t no_init{};
444
445
// Implements the storage of the values, and ensures that the destructor is
446
// trivial if it can be.
447
//
448
// This specialization is for where neither `T` or `E` is trivially
449
// destructible, so the destructors must be called on destruction of the
450
// `expected`
451
template <class T, class E, bool = std::is_trivially_destructible<T>::value,
452
          bool = std::is_trivially_destructible<E>::value>
453
struct expected_storage_base {
454
  constexpr expected_storage_base() : m_val(T{}), m_has_val(true) {}
455
  constexpr expected_storage_base(no_init_t) : m_no_init(), m_has_val(false) {}
456
457
  template <class... Args,
458
            detail::enable_if_t<std::is_constructible<T, Args &&...>::value> * =
459
                nullptr>
460
  constexpr expected_storage_base(in_place_t, Args &&...args)
461
3
      : m_val(std::forward<Args>(args)...), m_has_val(true) {}
_ZN2tl6detail21expected_storage_baseISt7variantIJSt10shared_ptrIN5doris10segment_v212idx_query_v213ConjunctionOpEES3_INS6_13DisjunctionOpEES3_INS6_12BooleanQueryEES3_INS6_9TermQueryEES3_INS6_12RoaringQueryEEEENS4_6StatusELb0ELb0EEC2IJSG_ELPv0EEENS_10in_place_tEDpOT_
Line
Count
Source
461
1
      : m_val(std::forward<Args>(args)...), m_has_val(true) {}
_ZN2tl6detail21expected_storage_baseISt7variantIJSt10shared_ptrIN5doris10segment_v212idx_query_v213ConjunctionOpEES3_INS6_13DisjunctionOpEES3_INS6_12BooleanQueryEES3_INS6_9TermQueryEES3_INS6_12RoaringQueryEEEENS4_6StatusELb0ELb0EEC2IJSE_ELPv0EEENS_10in_place_tEDpOT_
Line
Count
Source
461
2
      : m_val(std::forward<Args>(args)...), m_has_val(true) {}
462
463
  template <class U, class... Args,
464
            detail::enable_if_t<std::is_constructible<
465
                T, std::initializer_list<U> &, Args &&...>::value> * = nullptr>
466
  constexpr expected_storage_base(in_place_t, std::initializer_list<U> il,
467
                                  Args &&...args)
468
      : m_val(il, std::forward<Args>(args)...), m_has_val(true) {}
469
  template <class... Args,
470
            detail::enable_if_t<std::is_constructible<E, Args &&...>::value> * =
471
                nullptr>
472
  constexpr explicit expected_storage_base(unexpect_t, Args &&...args)
473
0
      : m_unexpect(std::forward<Args>(args)...), m_has_val(false) {}
474
475
  template <class U, class... Args,
476
            detail::enable_if_t<std::is_constructible<
477
                E, std::initializer_list<U> &, Args &&...>::value> * = nullptr>
478
  constexpr explicit expected_storage_base(unexpect_t,
479
                                           std::initializer_list<U> il,
480
                                           Args &&...args)
481
      : m_unexpect(il, std::forward<Args>(args)...), m_has_val(false) {}
482
483
5.94k
  ~expected_storage_base() {
484
5.94k
    if (m_has_val) {
485
5.94k
      m_val.~T();
486
5.94k
    } else {
487
0
      m_unexpect.~unexpected<E>();
488
0
    }
489
5.94k
  }
_ZN2tl6detail21expected_storage_baseISt10shared_ptrIN5doris2io12S3FileSystemEENS3_6StatusELb0ELb0EED2Ev
Line
Count
Source
483
2
  ~expected_storage_base() {
484
2
    if (m_has_val) {
485
2
      m_val.~T();
486
2
    } else {
487
0
      m_unexpect.~unexpected<E>();
488
0
    }
489
2
  }
_ZN2tl6detail21expected_storage_baseISt10unique_ptrIN5doris12RowsetWriterESt14default_deleteIS4_EENS3_6StatusELb0ELb0EED2Ev
Line
Count
Source
483
472
  ~expected_storage_base() {
484
472
    if (m_has_val) {
485
472
      m_val.~T();
486
472
    } else {
487
0
      m_unexpect.~unexpected<E>();
488
0
    }
489
472
  }
_ZN2tl6detail21expected_storage_baseISt7variantIJSt10shared_ptrIN6lucene6search13IndexSearcherEES3_INS4_4util3bkd10bkd_readerEEEEN5doris6StatusELb0ELb0EED2Ev
Line
Count
Source
483
12
  ~expected_storage_base() {
484
12
    if (m_has_val) {
485
12
      m_val.~T();
486
12
    } else {
487
0
      m_unexpect.~unexpected<E>();
488
0
    }
489
12
  }
_ZN2tl6detail21expected_storage_baseISt10unique_ptrIN5doris10segment_v219DorisCompoundReaderESt14default_deleteIS5_EENS3_6StatusELb0ELb0EED2Ev
Line
Count
Source
483
186
  ~expected_storage_base() {
484
186
    if (m_has_val) {
485
186
      m_val.~T();
486
186
    } else {
487
0
      m_unexpect.~unexpected<E>();
488
0
    }
489
186
  }
_ZN2tl6detail21expected_storage_baseISt3mapISt4pairIlNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEESt10shared_ptrIN6lucene5store9DirectoryEESt4lessISA_ESaIS3_IKSA_SF_EEEN5doris6StatusELb0ELb0EED2Ev
Line
Count
Source
483
23
  ~expected_storage_base() {
484
23
    if (m_has_val) {
485
23
      m_val.~T();
486
23
    } else {
487
0
      m_unexpect.~unexpected<E>();
488
0
    }
489
23
  }
_ZN2tl6detail21expected_storage_baseINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEN5doris6StatusELb0ELb0EED2Ev
Line
Count
Source
483
5.03k
  ~expected_storage_base() {
484
5.03k
    if (m_has_val) {
485
5.03k
      m_val.~T();
486
5.03k
    } else {
487
0
      m_unexpect.~unexpected<E>();
488
0
    }
489
5.03k
  }
_ZN2tl6detail21expected_storage_baseISt7variantIJSt10shared_ptrIN5doris10segment_v212idx_query_v213ConjunctionOpEES3_INS6_13DisjunctionOpEES3_INS6_12BooleanQueryEES3_INS6_9TermQueryEES3_INS6_12RoaringQueryEEEENS4_6StatusELb0ELb0EED2Ev
Line
Count
Source
483
7
  ~expected_storage_base() {
484
7
    if (m_has_val) {
485
7
      m_val.~T();
486
7
    } else {
487
0
      m_unexpect.~unexpected<E>();
488
0
    }
489
7
  }
_ZN2tl6detail21expected_storage_baseISt10shared_ptrIN5doris10segment_v216DorisFSDirectoryEENS3_6StatusELb0ELb0EED2Ev
Line
Count
Source
483
211
  ~expected_storage_base() {
484
211
    if (m_has_val) {
485
211
      m_val.~T();
486
211
    } else {
487
0
      m_unexpect.~unexpected<E>();
488
0
    }
489
211
  }
490
  union {
491
    T m_val;
492
    unexpected<E> m_unexpect;
493
    char m_no_init;
494
  };
495
  bool m_has_val;
496
};
497
498
// This specialization is for when both `T` and `E` are trivially-destructible,
499
// so the destructor of the `expected` can be trivial.
500
template <class T, class E> struct expected_storage_base<T, E, true, true> {
501
  constexpr expected_storage_base() : m_val(T{}), m_has_val(true) {}
502
  constexpr expected_storage_base(no_init_t) : m_no_init(), m_has_val(false) {}
503
504
  template <class... Args,
505
            detail::enable_if_t<std::is_constructible<T, Args &&...>::value> * =
506
                nullptr>
507
  constexpr expected_storage_base(in_place_t, Args &&...args)
508
      : m_val(std::forward<Args>(args)...), m_has_val(true) {}
509
510
  template <class U, class... Args,
511
            detail::enable_if_t<std::is_constructible<
512
                T, std::initializer_list<U> &, Args &&...>::value> * = nullptr>
513
  constexpr expected_storage_base(in_place_t, std::initializer_list<U> il,
514
                                  Args &&...args)
515
      : m_val(il, std::forward<Args>(args)...), m_has_val(true) {}
516
  template <class... Args,
517
            detail::enable_if_t<std::is_constructible<E, Args &&...>::value> * =
518
                nullptr>
519
  constexpr explicit expected_storage_base(unexpect_t, Args &&...args)
520
      : m_unexpect(std::forward<Args>(args)...), m_has_val(false) {}
521
522
  template <class U, class... Args,
523
            detail::enable_if_t<std::is_constructible<
524
                E, std::initializer_list<U> &, Args &&...>::value> * = nullptr>
525
  constexpr explicit expected_storage_base(unexpect_t,
526
                                           std::initializer_list<U> il,
527
                                           Args &&...args)
528
      : m_unexpect(il, std::forward<Args>(args)...), m_has_val(false) {}
529
530
  ~expected_storage_base() = default;
531
  union {
532
    T m_val;
533
    unexpected<E> m_unexpect;
534
    char m_no_init;
535
  };
536
  bool m_has_val;
537
};
538
539
// T is trivial, E is not.
540
template <class T, class E> struct expected_storage_base<T, E, true, false> {
541
  constexpr expected_storage_base() : m_val(T{}), m_has_val(true) {}
542
  TL_EXPECTED_MSVC2015_CONSTEXPR expected_storage_base(no_init_t)
543
      : m_no_init(), m_has_val(false) {}
544
545
  template <class... Args,
546
            detail::enable_if_t<std::is_constructible<T, Args &&...>::value> * =
547
                nullptr>
548
  constexpr expected_storage_base(in_place_t, Args &&...args)
549
      : m_val(std::forward<Args>(args)...), m_has_val(true) {}
550
551
  template <class U, class... Args,
552
            detail::enable_if_t<std::is_constructible<
553
                T, std::initializer_list<U> &, Args &&...>::value> * = nullptr>
554
  constexpr expected_storage_base(in_place_t, std::initializer_list<U> il,
555
                                  Args &&...args)
556
      : m_val(il, std::forward<Args>(args)...), m_has_val(true) {}
557
  template <class... Args,
558
            detail::enable_if_t<std::is_constructible<E, Args &&...>::value> * =
559
                nullptr>
560
  constexpr explicit expected_storage_base(unexpect_t, Args &&...args)
561
      : m_unexpect(std::forward<Args>(args)...), m_has_val(false) {}
562
563
  template <class U, class... Args,
564
            detail::enable_if_t<std::is_constructible<
565
                E, std::initializer_list<U> &, Args &&...>::value> * = nullptr>
566
  constexpr explicit expected_storage_base(unexpect_t,
567
                                           std::initializer_list<U> il,
568
                                           Args &&...args)
569
      : m_unexpect(il, std::forward<Args>(args)...), m_has_val(false) {}
570
571
  ~expected_storage_base() {
572
    if (!m_has_val) {
573
      m_unexpect.~unexpected<E>();
574
    }
575
  }
576
577
  union {
578
    T m_val;
579
    unexpected<E> m_unexpect;
580
    char m_no_init;
581
  };
582
  bool m_has_val;
583
};
584
585
// E is trivial, T is not.
586
template <class T, class E> struct expected_storage_base<T, E, false, true> {
587
  constexpr expected_storage_base() : m_val(T{}), m_has_val(true) {}
588
  constexpr expected_storage_base(no_init_t) : m_no_init(), m_has_val(false) {}
589
590
  template <class... Args,
591
            detail::enable_if_t<std::is_constructible<T, Args &&...>::value> * =
592
                nullptr>
593
  constexpr expected_storage_base(in_place_t, Args &&...args)
594
      : m_val(std::forward<Args>(args)...), m_has_val(true) {}
595
596
  template <class U, class... Args,
597
            detail::enable_if_t<std::is_constructible<
598
                T, std::initializer_list<U> &, Args &&...>::value> * = nullptr>
599
  constexpr expected_storage_base(in_place_t, std::initializer_list<U> il,
600
                                  Args &&...args)
601
      : m_val(il, std::forward<Args>(args)...), m_has_val(true) {}
602
  template <class... Args,
603
            detail::enable_if_t<std::is_constructible<E, Args &&...>::value> * =
604
                nullptr>
605
  constexpr explicit expected_storage_base(unexpect_t, Args &&...args)
606
      : m_unexpect(std::forward<Args>(args)...), m_has_val(false) {}
607
608
  template <class U, class... Args,
609
            detail::enable_if_t<std::is_constructible<
610
                E, std::initializer_list<U> &, Args &&...>::value> * = nullptr>
611
  constexpr explicit expected_storage_base(unexpect_t,
612
                                           std::initializer_list<U> il,
613
                                           Args &&...args)
614
      : m_unexpect(il, std::forward<Args>(args)...), m_has_val(false) {}
615
616
  ~expected_storage_base() {
617
    if (m_has_val) {
618
      m_val.~T();
619
    }
620
  }
621
  union {
622
    T m_val;
623
    unexpected<E> m_unexpect;
624
    char m_no_init;
625
  };
626
  bool m_has_val;
627
};
628
629
// `T` is `void`, `E` is trivially-destructible
630
template <class E> struct expected_storage_base<void, E, false, true> {
631
  #if __GNUC__ <= 5
632
  //no constexpr for GCC 4/5 bug
633
  #else
634
  TL_EXPECTED_MSVC2015_CONSTEXPR
635
  #endif 
636
  expected_storage_base() : m_has_val(true) {}
637
     
638
  constexpr expected_storage_base(no_init_t) : m_val(), m_has_val(false) {}
639
640
  constexpr expected_storage_base(in_place_t) : m_has_val(true) {}
641
642
  template <class... Args,
643
            detail::enable_if_t<std::is_constructible<E, Args &&...>::value> * =
644
                nullptr>
645
  constexpr explicit expected_storage_base(unexpect_t, Args &&...args)
646
      : m_unexpect(std::forward<Args>(args)...), m_has_val(false) {}
647
648
  template <class U, class... Args,
649
            detail::enable_if_t<std::is_constructible<
650
                E, std::initializer_list<U> &, Args &&...>::value> * = nullptr>
651
  constexpr explicit expected_storage_base(unexpect_t,
652
                                           std::initializer_list<U> il,
653
                                           Args &&...args)
654
      : m_unexpect(il, std::forward<Args>(args)...), m_has_val(false) {}
655
656
  ~expected_storage_base() = default;
657
  struct dummy {};
658
  union {
659
    unexpected<E> m_unexpect;
660
    dummy m_val;
661
  };
662
  bool m_has_val;
663
};
664
665
// `T` is `void`, `E` is not trivially-destructible
666
template <class E> struct expected_storage_base<void, E, false, false> {
667
  constexpr expected_storage_base() : m_dummy(), m_has_val(true) {}
668
  constexpr expected_storage_base(no_init_t) : m_dummy(), m_has_val(false) {}
669
670
  constexpr expected_storage_base(in_place_t) : m_dummy(), m_has_val(true) {}
671
672
  template <class... Args,
673
            detail::enable_if_t<std::is_constructible<E, Args &&...>::value> * =
674
                nullptr>
675
  constexpr explicit expected_storage_base(unexpect_t, Args &&...args)
676
      : m_unexpect(std::forward<Args>(args)...), m_has_val(false) {}
677
678
  template <class U, class... Args,
679
            detail::enable_if_t<std::is_constructible<
680
                E, std::initializer_list<U> &, Args &&...>::value> * = nullptr>
681
  constexpr explicit expected_storage_base(unexpect_t,
682
                                           std::initializer_list<U> il,
683
                                           Args &&...args)
684
      : m_unexpect(il, std::forward<Args>(args)...), m_has_val(false) {}
685
686
  ~expected_storage_base() {
687
    if (!m_has_val) {
688
      m_unexpect.~unexpected<E>();
689
    }
690
  }
691
692
  union {
693
    unexpected<E> m_unexpect;
694
    char m_dummy;
695
  };
696
  bool m_has_val;
697
};
698
699
// This base class provides some handy member functions which can be used in
700
// further derived classes
701
template <class T, class E>
702
struct expected_operations_base : expected_storage_base<T, E> {
703
  using expected_storage_base<T, E>::expected_storage_base;
704
705
  template <class... Args> void construct(Args &&...args) noexcept {
706
    new (std::addressof(this->m_val)) T(std::forward<Args>(args)...);
707
    this->m_has_val = true;
708
  }
709
710
  template <class Rhs> void construct_with(Rhs &&rhs) noexcept {
711
    new (std::addressof(this->m_val)) T(std::forward<Rhs>(rhs).get());
712
    this->m_has_val = true;
713
  }
714
715
  template <class... Args> void construct_error(Args &&...args) noexcept {
716
    new (std::addressof(this->m_unexpect))
717
        unexpected<E>(std::forward<Args>(args)...);
718
    this->m_has_val = false;
719
  }
720
721
#ifdef TL_EXPECTED_EXCEPTIONS_ENABLED
722
723
  // These assign overloads ensure that the most efficient assignment
724
  // implementation is used while maintaining the strong exception guarantee.
725
  // The problematic case is where rhs has a value, but *this does not.
726
  //
727
  // This overload handles the case where we can just copy-construct `T`
728
  // directly into place without throwing.
729
  template <class U = T,
730
            detail::enable_if_t<std::is_nothrow_copy_constructible<U>::value>
731
                * = nullptr>
732
  void assign(const expected_operations_base &rhs) noexcept {
733
    if (!this->m_has_val && rhs.m_has_val) {
734
      geterr().~unexpected<E>();
735
      construct(rhs.get());
736
    } else {
737
      assign_common(rhs);
738
    }
739
  }
740
741
  // This overload handles the case where we can attempt to create a copy of
742
  // `T`, then no-throw move it into place if the copy was successful.
743
  template <class U = T,
744
            detail::enable_if_t<!std::is_nothrow_copy_constructible<U>::value &&
745
                                std::is_nothrow_move_constructible<U>::value>
746
                * = nullptr>
747
  void assign(const expected_operations_base &rhs) noexcept {
748
    if (!this->m_has_val && rhs.m_has_val) {
749
      T tmp = rhs.get();
750
      geterr().~unexpected<E>();
751
      construct(std::move(tmp));
752
    } else {
753
      assign_common(rhs);
754
    }
755
  }
756
757
  // This overload is the worst-case, where we have to move-construct the
758
  // unexpected value into temporary storage, then try to copy the T into place.
759
  // If the construction succeeds, then everything is fine, but if it throws,
760
  // then we move the old unexpected value back into place before rethrowing the
761
  // exception.
762
  template <class U = T,
763
            detail::enable_if_t<!std::is_nothrow_copy_constructible<U>::value &&
764
                                !std::is_nothrow_move_constructible<U>::value>
765
                * = nullptr>
766
  void assign(const expected_operations_base &rhs) {
767
    if (!this->m_has_val && rhs.m_has_val) {
768
      auto tmp = std::move(geterr());
769
      geterr().~unexpected<E>();
770
771
#ifdef TL_EXPECTED_EXCEPTIONS_ENABLED
772
      try {
773
        construct(rhs.get());
774
      } catch (...) {
775
        geterr() = std::move(tmp);
776
        throw;
777
      }
778
#else
779
      construct(rhs.get());
780
#endif
781
    } else {
782
      assign_common(rhs);
783
    }
784
  }
785
786
  // These overloads do the same as above, but for rvalues
787
  template <class U = T,
788
            detail::enable_if_t<std::is_nothrow_move_constructible<U>::value>
789
                * = nullptr>
790
  void assign(expected_operations_base &&rhs) noexcept {
791
    if (!this->m_has_val && rhs.m_has_val) {
792
      geterr().~unexpected<E>();
793
      construct(std::move(rhs).get());
794
    } else {
795
      assign_common(std::move(rhs));
796
    }
797
  }
798
799
  template <class U = T,
800
            detail::enable_if_t<!std::is_nothrow_move_constructible<U>::value>
801
                * = nullptr>
802
  void assign(expected_operations_base &&rhs) {
803
    if (!this->m_has_val && rhs.m_has_val) {
804
      auto tmp = std::move(geterr());
805
      geterr().~unexpected<E>();
806
#ifdef TL_EXPECTED_EXCEPTIONS_ENABLED
807
      try {
808
        construct(std::move(rhs).get());
809
      } catch (...) {
810
        geterr() = std::move(tmp);
811
        throw;
812
      }
813
#else
814
      construct(std::move(rhs).get());
815
#endif
816
    } else {
817
      assign_common(std::move(rhs));
818
    }
819
  }
820
821
#else
822
823
  // If exceptions are disabled then we can just copy-construct
824
  void assign(const expected_operations_base &rhs) noexcept {
825
    if (!this->m_has_val && rhs.m_has_val) {
826
      geterr().~unexpected<E>();
827
      construct(rhs.get());
828
    } else {
829
      assign_common(rhs);
830
    }
831
  }
832
833
  void assign(expected_operations_base &&rhs) noexcept {
834
    if (!this->m_has_val && rhs.m_has_val) {
835
      geterr().~unexpected<E>();
836
      construct(std::move(rhs).get());
837
    } else {
838
      assign_common(std::move(rhs));
839
    }
840
  }
841
842
#endif
843
844
  // The common part of move/copy assigning
845
  template <class Rhs> void assign_common(Rhs &&rhs) {
846
    if (this->m_has_val) {
847
      if (rhs.m_has_val) {
848
        get() = std::forward<Rhs>(rhs).get();
849
      } else {
850
        destroy_val();
851
        construct_error(std::forward<Rhs>(rhs).geterr());
852
      }
853
    } else {
854
      if (!rhs.m_has_val) {
855
        geterr() = std::forward<Rhs>(rhs).geterr();
856
      }
857
    }
858
  }
859
860
  bool has_value() const { return this->m_has_val; }
861
862
  TL_EXPECTED_11_CONSTEXPR T &get() & { return this->m_val; }
863
  constexpr const T &get() const & { return this->m_val; }
864
  TL_EXPECTED_11_CONSTEXPR T &&get() && { return std::move(this->m_val); }
865
#ifndef TL_EXPECTED_NO_CONSTRR
866
  constexpr const T &&get() const && { return std::move(this->m_val); }
867
#endif
868
869
  TL_EXPECTED_11_CONSTEXPR unexpected<E> &geterr() & {
870
    return this->m_unexpect;
871
  }
872
  constexpr const unexpected<E> &geterr() const & { return this->m_unexpect; }
873
  TL_EXPECTED_11_CONSTEXPR unexpected<E> &&geterr() && {
874
    return std::move(this->m_unexpect);
875
  }
876
#ifndef TL_EXPECTED_NO_CONSTRR
877
  constexpr const unexpected<E> &&geterr() const && {
878
    return std::move(this->m_unexpect);
879
  }
880
#endif
881
882
  TL_EXPECTED_11_CONSTEXPR void destroy_val() { get().~T(); }
883
};
884
885
// This base class provides some handy member functions which can be used in
886
// further derived classes
887
template <class E>
888
struct expected_operations_base<void, E> : expected_storage_base<void, E> {
889
  using expected_storage_base<void, E>::expected_storage_base;
890
891
  template <class... Args> void construct() noexcept { this->m_has_val = true; }
892
893
  // This function doesn't use its argument, but needs it so that code in
894
  // levels above this can work independently of whether T is void
895
  template <class Rhs> void construct_with(Rhs &&) noexcept {
896
    this->m_has_val = true;
897
  }
898
899
  template <class... Args> void construct_error(Args &&...args) noexcept {
900
    new (std::addressof(this->m_unexpect))
901
        unexpected<E>(std::forward<Args>(args)...);
902
    this->m_has_val = false;
903
  }
904
905
  template <class Rhs> void assign(Rhs &&rhs) noexcept {
906
    if (!this->m_has_val) {
907
      if (rhs.m_has_val) {
908
        geterr().~unexpected<E>();
909
        construct();
910
      } else {
911
        geterr() = std::forward<Rhs>(rhs).geterr();
912
      }
913
    } else {
914
      if (!rhs.m_has_val) {
915
        construct_error(std::forward<Rhs>(rhs).geterr());
916
      }
917
    }
918
  }
919
920
  bool has_value() const { return this->m_has_val; }
921
922
  TL_EXPECTED_11_CONSTEXPR unexpected<E> &geterr() & {
923
    return this->m_unexpect;
924
  }
925
  constexpr const unexpected<E> &geterr() const & { return this->m_unexpect; }
926
  TL_EXPECTED_11_CONSTEXPR unexpected<E> &&geterr() && {
927
    return std::move(this->m_unexpect);
928
  }
929
#ifndef TL_EXPECTED_NO_CONSTRR
930
  constexpr const unexpected<E> &&geterr() const && {
931
    return std::move(this->m_unexpect);
932
  }
933
#endif
934
935
  TL_EXPECTED_11_CONSTEXPR void destroy_val() {
936
    // no-op
937
  }
938
};
939
940
// This class manages conditionally having a trivial copy constructor
941
// This specialization is for when T and E are trivially copy constructible
942
template <class T, class E,
943
          bool = is_void_or<T, TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T)>::
944
              value &&TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(E)::value>
945
struct expected_copy_base : expected_operations_base<T, E> {
946
  using expected_operations_base<T, E>::expected_operations_base;
947
};
948
949
// This specialization is for when T or E are not trivially copy constructible
950
template <class T, class E>
951
struct expected_copy_base<T, E, false> : expected_operations_base<T, E> {
952
  using expected_operations_base<T, E>::expected_operations_base;
953
954
  expected_copy_base() = default;
955
  expected_copy_base(const expected_copy_base &rhs)
956
      : expected_operations_base<T, E>(no_init) {
957
    if (rhs.has_value()) {
958
      this->construct_with(rhs);
959
    } else {
960
      this->construct_error(rhs.geterr());
961
    }
962
  }
963
964
  expected_copy_base(expected_copy_base &&rhs) = default;
965
  expected_copy_base &operator=(const expected_copy_base &rhs) = default;
966
  expected_copy_base &operator=(expected_copy_base &&rhs) = default;
967
};
968
969
// This class manages conditionally having a trivial move constructor
970
// Unfortunately there's no way to achieve this in GCC < 5 AFAIK, since it
971
// doesn't implement an analogue to std::is_trivially_move_constructible. We
972
// have to make do with a non-trivial move constructor even if T is trivially
973
// move constructible
974
#ifndef TL_EXPECTED_GCC49
975
template <class T, class E,
976
          bool = is_void_or<T, std::is_trivially_move_constructible<T>>::value
977
              &&std::is_trivially_move_constructible<E>::value>
978
struct expected_move_base : expected_copy_base<T, E> {
979
  using expected_copy_base<T, E>::expected_copy_base;
980
};
981
#else
982
template <class T, class E, bool = false> struct expected_move_base;
983
#endif
984
template <class T, class E>
985
struct expected_move_base<T, E, false> : expected_copy_base<T, E> {
986
  using expected_copy_base<T, E>::expected_copy_base;
987
988
  expected_move_base() = default;
989
  expected_move_base(const expected_move_base &rhs) = default;
990
991
  expected_move_base(expected_move_base &&rhs) noexcept(
992
      std::is_nothrow_move_constructible<T>::value)
993
      : expected_copy_base<T, E>(no_init) {
994
    if (rhs.has_value()) {
995
      this->construct_with(std::move(rhs));
996
    } else {
997
      this->construct_error(std::move(rhs.geterr()));
998
    }
999
  }
1000
  expected_move_base &operator=(const expected_move_base &rhs) = default;
1001
  expected_move_base &operator=(expected_move_base &&rhs) = default;
1002
};
1003
1004
// This class manages conditionally having a trivial copy assignment operator
1005
template <class T, class E,
1006
          bool = is_void_or<
1007
              T, conjunction<TL_EXPECTED_IS_TRIVIALLY_COPY_ASSIGNABLE(T),
1008
                             TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T),
1009
                             TL_EXPECTED_IS_TRIVIALLY_DESTRUCTIBLE(T)>>::value
1010
              &&TL_EXPECTED_IS_TRIVIALLY_COPY_ASSIGNABLE(E)::value
1011
                  &&TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(E)::value
1012
                      &&TL_EXPECTED_IS_TRIVIALLY_DESTRUCTIBLE(E)::value>
1013
struct expected_copy_assign_base : expected_move_base<T, E> {
1014
  using expected_move_base<T, E>::expected_move_base;
1015
};
1016
1017
template <class T, class E>
1018
struct expected_copy_assign_base<T, E, false> : expected_move_base<T, E> {
1019
  using expected_move_base<T, E>::expected_move_base;
1020
1021
  expected_copy_assign_base() = default;
1022
  expected_copy_assign_base(const expected_copy_assign_base &rhs) = default;
1023
1024
  expected_copy_assign_base(expected_copy_assign_base &&rhs) = default;
1025
  expected_copy_assign_base &operator=(const expected_copy_assign_base &rhs) {
1026
    this->assign(rhs);
1027
    return *this;
1028
  }
1029
  expected_copy_assign_base &
1030
  operator=(expected_copy_assign_base &&rhs) = default;
1031
};
1032
1033
// This class manages conditionally having a trivial move assignment operator
1034
// Unfortunately there's no way to achieve this in GCC < 5 AFAIK, since it
1035
// doesn't implement an analogue to std::is_trivially_move_assignable. We have
1036
// to make do with a non-trivial move assignment operator even if T is trivially
1037
// move assignable
1038
#ifndef TL_EXPECTED_GCC49
1039
template <class T, class E,
1040
          bool =
1041
              is_void_or<T, conjunction<std::is_trivially_destructible<T>,
1042
                                        std::is_trivially_move_constructible<T>,
1043
                                        std::is_trivially_move_assignable<T>>>::
1044
                  value &&std::is_trivially_destructible<E>::value
1045
                      &&std::is_trivially_move_constructible<E>::value
1046
                          &&std::is_trivially_move_assignable<E>::value>
1047
struct expected_move_assign_base : expected_copy_assign_base<T, E> {
1048
  using expected_copy_assign_base<T, E>::expected_copy_assign_base;
1049
};
1050
#else
1051
template <class T, class E, bool = false> struct expected_move_assign_base;
1052
#endif
1053
1054
template <class T, class E>
1055
struct expected_move_assign_base<T, E, false>
1056
    : expected_copy_assign_base<T, E> {
1057
  using expected_copy_assign_base<T, E>::expected_copy_assign_base;
1058
1059
  expected_move_assign_base() = default;
1060
  expected_move_assign_base(const expected_move_assign_base &rhs) = default;
1061
1062
  expected_move_assign_base(expected_move_assign_base &&rhs) = default;
1063
1064
  expected_move_assign_base &
1065
  operator=(const expected_move_assign_base &rhs) = default;
1066
1067
  expected_move_assign_base &
1068
  operator=(expected_move_assign_base &&rhs) noexcept(
1069
      std::is_nothrow_move_constructible<T>::value
1070
          &&std::is_nothrow_move_assignable<T>::value) {
1071
    this->assign(std::move(rhs));
1072
    return *this;
1073
  }
1074
};
1075
1076
// expected_delete_ctor_base will conditionally delete copy and move
1077
// constructors depending on whether T is copy/move constructible
1078
template <class T, class E,
1079
          bool EnableCopy = (is_copy_constructible_or_void<T>::value &&
1080
                             std::is_copy_constructible<E>::value),
1081
          bool EnableMove = (is_move_constructible_or_void<T>::value &&
1082
                             std::is_move_constructible<E>::value)>
1083
struct expected_delete_ctor_base {
1084
  expected_delete_ctor_base() = default;
1085
  expected_delete_ctor_base(const expected_delete_ctor_base &) = default;
1086
  expected_delete_ctor_base(expected_delete_ctor_base &&) noexcept = default;
1087
  expected_delete_ctor_base &
1088
  operator=(const expected_delete_ctor_base &) = default;
1089
  expected_delete_ctor_base &
1090
  operator=(expected_delete_ctor_base &&) noexcept = default;
1091
};
1092
1093
template <class T, class E>
1094
struct expected_delete_ctor_base<T, E, true, false> {
1095
  expected_delete_ctor_base() = default;
1096
  expected_delete_ctor_base(const expected_delete_ctor_base &) = default;
1097
  expected_delete_ctor_base(expected_delete_ctor_base &&) noexcept = delete;
1098
  expected_delete_ctor_base &
1099
  operator=(const expected_delete_ctor_base &) = default;
1100
  expected_delete_ctor_base &
1101
  operator=(expected_delete_ctor_base &&) noexcept = default;
1102
};
1103
1104
template <class T, class E>
1105
struct expected_delete_ctor_base<T, E, false, true> {
1106
  expected_delete_ctor_base() = default;
1107
  expected_delete_ctor_base(const expected_delete_ctor_base &) = delete;
1108
  expected_delete_ctor_base(expected_delete_ctor_base &&) noexcept = default;
1109
  expected_delete_ctor_base &
1110
  operator=(const expected_delete_ctor_base &) = default;
1111
  expected_delete_ctor_base &
1112
  operator=(expected_delete_ctor_base &&) noexcept = default;
1113
};
1114
1115
template <class T, class E>
1116
struct expected_delete_ctor_base<T, E, false, false> {
1117
  expected_delete_ctor_base() = default;
1118
  expected_delete_ctor_base(const expected_delete_ctor_base &) = delete;
1119
  expected_delete_ctor_base(expected_delete_ctor_base &&) noexcept = delete;
1120
  expected_delete_ctor_base &
1121
  operator=(const expected_delete_ctor_base &) = default;
1122
  expected_delete_ctor_base &
1123
  operator=(expected_delete_ctor_base &&) noexcept = default;
1124
};
1125
1126
// expected_delete_assign_base will conditionally delete copy and move
1127
// constructors depending on whether T and E are copy/move constructible +
1128
// assignable
1129
template <class T, class E,
1130
          bool EnableCopy = (is_copy_constructible_or_void<T>::value &&
1131
                             std::is_copy_constructible<E>::value &&
1132
                             is_copy_assignable_or_void<T>::value &&
1133
                             std::is_copy_assignable<E>::value),
1134
          bool EnableMove = (is_move_constructible_or_void<T>::value &&
1135
                             std::is_move_constructible<E>::value &&
1136
                             is_move_assignable_or_void<T>::value &&
1137
                             std::is_move_assignable<E>::value)>
1138
struct expected_delete_assign_base {
1139
  expected_delete_assign_base() = default;
1140
  expected_delete_assign_base(const expected_delete_assign_base &) = default;
1141
  expected_delete_assign_base(expected_delete_assign_base &&) noexcept =
1142
      default;
1143
  expected_delete_assign_base &
1144
  operator=(const expected_delete_assign_base &) = default;
1145
  expected_delete_assign_base &
1146
  operator=(expected_delete_assign_base &&) noexcept = default;
1147
};
1148
1149
template <class T, class E>
1150
struct expected_delete_assign_base<T, E, true, false> {
1151
  expected_delete_assign_base() = default;
1152
  expected_delete_assign_base(const expected_delete_assign_base &) = default;
1153
  expected_delete_assign_base(expected_delete_assign_base &&) noexcept =
1154
      default;
1155
  expected_delete_assign_base &
1156
  operator=(const expected_delete_assign_base &) = default;
1157
  expected_delete_assign_base &
1158
  operator=(expected_delete_assign_base &&) noexcept = delete;
1159
};
1160
1161
template <class T, class E>
1162
struct expected_delete_assign_base<T, E, false, true> {
1163
  expected_delete_assign_base() = default;
1164
  expected_delete_assign_base(const expected_delete_assign_base &) = default;
1165
  expected_delete_assign_base(expected_delete_assign_base &&) noexcept =
1166
      default;
1167
  expected_delete_assign_base &
1168
  operator=(const expected_delete_assign_base &) = delete;
1169
  expected_delete_assign_base &
1170
  operator=(expected_delete_assign_base &&) noexcept = default;
1171
};
1172
1173
template <class T, class E>
1174
struct expected_delete_assign_base<T, E, false, false> {
1175
  expected_delete_assign_base() = default;
1176
  expected_delete_assign_base(const expected_delete_assign_base &) = default;
1177
  expected_delete_assign_base(expected_delete_assign_base &&) noexcept =
1178
      default;
1179
  expected_delete_assign_base &
1180
  operator=(const expected_delete_assign_base &) = delete;
1181
  expected_delete_assign_base &
1182
  operator=(expected_delete_assign_base &&) noexcept = delete;
1183
};
1184
1185
// This is needed to be able to construct the expected_default_ctor_base which
1186
// follows, while still conditionally deleting the default constructor.
1187
struct default_constructor_tag {
1188
  explicit constexpr default_constructor_tag() = default;
1189
};
1190
1191
// expected_default_ctor_base will ensure that expected has a deleted default
1192
// consturctor if T is not default constructible.
1193
// This specialization is for when T is default constructible
1194
template <class T, class E,
1195
          bool Enable =
1196
              std::is_default_constructible<T>::value || std::is_void<T>::value>
1197
struct expected_default_ctor_base {
1198
  constexpr expected_default_ctor_base() noexcept = default;
1199
  constexpr expected_default_ctor_base(
1200
      expected_default_ctor_base const &) noexcept = default;
1201
  constexpr expected_default_ctor_base(expected_default_ctor_base &&) noexcept =
1202
      default;
1203
  expected_default_ctor_base &
1204
  operator=(expected_default_ctor_base const &) noexcept = default;
1205
  expected_default_ctor_base &
1206
  operator=(expected_default_ctor_base &&) noexcept = default;
1207
1208
7
  constexpr explicit expected_default_ctor_base(default_constructor_tag) {}
1209
};
1210
1211
// This specialization is for when T is not default constructible
1212
template <class T, class E> struct expected_default_ctor_base<T, E, false> {
1213
  constexpr expected_default_ctor_base() noexcept = delete;
1214
  constexpr expected_default_ctor_base(
1215
      expected_default_ctor_base const &) noexcept = default;
1216
  constexpr expected_default_ctor_base(expected_default_ctor_base &&) noexcept =
1217
      default;
1218
  expected_default_ctor_base &
1219
  operator=(expected_default_ctor_base const &) noexcept = default;
1220
  expected_default_ctor_base &
1221
  operator=(expected_default_ctor_base &&) noexcept = default;
1222
1223
  constexpr explicit expected_default_ctor_base(default_constructor_tag) {}
1224
};
1225
} // namespace detail
1226
1227
template <class E> class bad_expected_access : public std::exception {
1228
public:
1229
0
  explicit bad_expected_access(E e) : m_val(std::move(e)) {}
1230
1231
0
  virtual const char *what() const noexcept override {
1232
0
    return "Bad expected access";
1233
0
  }
1234
1235
  const E &error() const & { return m_val; }
1236
  E &error() & { return m_val; }
1237
  const E &&error() const && { return std::move(m_val); }
1238
  E &&error() && { return std::move(m_val); }
1239
1240
private:
1241
  E m_val;
1242
};
1243
1244
/// An `expected<T, E>` object is an object that contains the storage for
1245
/// another object and manages the lifetime of this contained object `T`.
1246
/// Alternatively it could contain the storage for another unexpected object
1247
/// `E`. The contained object may not be initialized after the expected object
1248
/// has been initialized, and may not be destroyed before the expected object
1249
/// has been destroyed. The initialization state of the contained object is
1250
/// tracked by the expected object.
1251
template <class T, class E>
1252
class expected : private detail::expected_move_assign_base<T, E>,
1253
                 private detail::expected_delete_ctor_base<T, E>,
1254
                 private detail::expected_delete_assign_base<T, E>,
1255
                 private detail::expected_default_ctor_base<T, E> {
1256
  static_assert(!std::is_reference<T>::value, "T must not be a reference");
1257
  static_assert(!std::is_same<T, std::remove_cv<in_place_t>::type>::value,
1258
                "T must not be in_place_t");
1259
  static_assert(!std::is_same<T, std::remove_cv<unexpect_t>::type>::value,
1260
                "T must not be unexpect_t");
1261
  static_assert(
1262
      !std::is_same<T, typename std::remove_cv<unexpected<E>>::type>::value,
1263
      "T must not be unexpected<E>");
1264
  static_assert(!std::is_reference<E>::value, "E must not be a reference");
1265
1266
4
  T *valptr() { return std::addressof(this->m_val); }
1267
  const T *valptr() const { return std::addressof(this->m_val); }
1268
  unexpected<E> *errptr() { return std::addressof(this->m_unexpect); }
1269
  const unexpected<E> *errptr() const {
1270
    return std::addressof(this->m_unexpect);
1271
  }
1272
1273
  template <class U = T,
1274
            detail::enable_if_t<!std::is_void<U>::value> * = nullptr>
1275
883
  TL_EXPECTED_11_CONSTEXPR U &val() {
1276
883
    return this->m_val;
1277
883
  }
_ZN2tl8expectedISt10shared_ptrIN5doris2io12S3FileSystemEENS2_6StatusEE3valIS5_LPv0EEERT_v
Line
Count
Source
1275
2
  TL_EXPECTED_11_CONSTEXPR U &val() {
1276
2
    return this->m_val;
1277
2
  }
_ZN2tl8expectedISt10unique_ptrIN5doris12RowsetWriterESt14default_deleteIS3_EENS2_6StatusEE3valIS6_LPv0EEERT_v
Line
Count
Source
1275
467
  TL_EXPECTED_11_CONSTEXPR U &val() {
1276
467
    return this->m_val;
1277
467
  }
_ZN2tl8expectedISt10unique_ptrIN5doris10segment_v219DorisCompoundReaderESt14default_deleteIS4_EENS2_6StatusEE3valIS7_LPv0EEERT_v
Line
Count
Source
1275
184
  TL_EXPECTED_11_CONSTEXPR U &val() {
1276
184
    return this->m_val;
1277
184
  }
_ZN2tl8expectedISt7variantIJSt10shared_ptrIN6lucene6search13IndexSearcherEES2_INS3_4util3bkd10bkd_readerEEEEN5doris6StatusEE3valISB_LPv0EEERT_v
Line
Count
Source
1275
12
  TL_EXPECTED_11_CONSTEXPR U &val() {
1276
12
    return this->m_val;
1277
12
  }
_ZN2tl8expectedISt7variantIJSt10shared_ptrIN5doris10segment_v212idx_query_v213ConjunctionOpEES2_INS5_13DisjunctionOpEES2_INS5_12BooleanQueryEES2_INS5_9TermQueryEES2_INS5_12RoaringQueryEEEENS3_6StatusEE3valISG_LPv0EEERT_v
Line
Count
Source
1275
7
  TL_EXPECTED_11_CONSTEXPR U &val() {
1276
7
    return this->m_val;
1277
7
  }
_ZN2tl8expectedISt10shared_ptrIN5doris10segment_v216DorisFSDirectoryEENS2_6StatusEE3valIS5_LPv0EEERT_v
Line
Count
Source
1275
211
  TL_EXPECTED_11_CONSTEXPR U &val() {
1276
211
    return this->m_val;
1277
211
  }
1278
0
  TL_EXPECTED_11_CONSTEXPR unexpected<E> &err() { return this->m_unexpect; }
Unexecuted instantiation: _ZN2tl8expectedISt10shared_ptrIN5doris2io12S3FileSystemEENS2_6StatusEE3errEv
Unexecuted instantiation: _ZN2tl8expectedISt10unique_ptrIN5doris12RowsetWriterESt14default_deleteIS3_EENS2_6StatusEE3errEv
Unexecuted instantiation: _ZN2tl8expectedISt10unique_ptrIN5doris10segment_v219DorisCompoundReaderESt14default_deleteIS4_EENS2_6StatusEE3errEv
Unexecuted instantiation: _ZN2tl8expectedISt7variantIJSt10shared_ptrIN6lucene6search13IndexSearcherEES2_INS3_4util3bkd10bkd_readerEEEEN5doris6StatusEE3errEv
Unexecuted instantiation: _ZN2tl8expectedISt7variantIJSt10shared_ptrIN5doris10segment_v212idx_query_v213ConjunctionOpEES2_INS5_13DisjunctionOpEES2_INS5_12BooleanQueryEES2_INS5_9TermQueryEES2_INS5_12RoaringQueryEEEENS3_6StatusEE3errEv
Unexecuted instantiation: _ZN2tl8expectedISt10shared_ptrIN5doris10segment_v216DorisFSDirectoryEENS2_6StatusEE3errEv
1279
1280
  template <class U = T,
1281
            detail::enable_if_t<!std::is_void<U>::value> * = nullptr>
1282
53
  constexpr const U &val() const {
1283
53
    return this->m_val;
1284
53
  }
_ZNK2tl8expectedISt10unique_ptrIN5doris12RowsetWriterESt14default_deleteIS3_EENS2_6StatusEE3valIS6_LPv0EEERKT_v
Line
Count
Source
1282
5
  constexpr const U &val() const {
1283
5
    return this->m_val;
1284
5
  }
_ZNK2tl8expectedINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEN5doris6StatusEE3valIS6_LPv0EEERKT_v
Line
Count
Source
1282
25
  constexpr const U &val() const {
1283
25
    return this->m_val;
1284
25
  }
_ZNK2tl8expectedISt3mapISt4pairIlNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEESt10shared_ptrIN6lucene5store9DirectoryEESt4lessIS9_ESaIS2_IKS9_SE_EEEN5doris6StatusEE3valISK_LPv0EEERKT_v
Line
Count
Source
1282
23
  constexpr const U &val() const {
1283
23
    return this->m_val;
1284
23
  }
1285
0
  constexpr const unexpected<E> &err() const { return this->m_unexpect; }
Unexecuted instantiation: _ZNK2tl8expectedISt10unique_ptrIN5doris12RowsetWriterESt14default_deleteIS3_EENS2_6StatusEE3errEv
Unexecuted instantiation: _ZNK2tl8expectedINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEN5doris6StatusEE3errEv
Unexecuted instantiation: _ZNK2tl8expectedISt3mapISt4pairIlNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEESt10shared_ptrIN6lucene5store9DirectoryEESt4lessIS9_ESaIS2_IKS9_SE_EEEN5doris6StatusEE3errEv
1286
1287
  using impl_base = detail::expected_move_assign_base<T, E>;
1288
  using ctor_base = detail::expected_default_ctor_base<T, E>;
1289
1290
public:
1291
  typedef T value_type;
1292
  typedef E error_type;
1293
  typedef unexpected<E> unexpected_type;
1294
1295
#if defined(TL_EXPECTED_CXX14) && !defined(TL_EXPECTED_GCC49) &&               \
1296
    !defined(TL_EXPECTED_GCC54) && !defined(TL_EXPECTED_GCC55)
1297
  template <class F> TL_EXPECTED_11_CONSTEXPR auto and_then(F &&f) & {
1298
    return and_then_impl(*this, std::forward<F>(f));
1299
  }
1300
  template <class F> TL_EXPECTED_11_CONSTEXPR auto and_then(F &&f) && {
1301
    return and_then_impl(std::move(*this), std::forward<F>(f));
1302
  }
1303
  template <class F> constexpr auto and_then(F &&f) const & {
1304
    return and_then_impl(*this, std::forward<F>(f));
1305
  }
1306
1307
#ifndef TL_EXPECTED_NO_CONSTRR
1308
  template <class F> constexpr auto and_then(F &&f) const && {
1309
    return and_then_impl(std::move(*this), std::forward<F>(f));
1310
  }
1311
#endif
1312
1313
#else
1314
  template <class F>
1315
  TL_EXPECTED_11_CONSTEXPR auto
1316
  and_then(F &&f) & -> decltype(and_then_impl(std::declval<expected &>(),
1317
                                              std::forward<F>(f))) {
1318
    return and_then_impl(*this, std::forward<F>(f));
1319
  }
1320
  template <class F>
1321
  TL_EXPECTED_11_CONSTEXPR auto
1322
  and_then(F &&f) && -> decltype(and_then_impl(std::declval<expected &&>(),
1323
                                               std::forward<F>(f))) {
1324
    return and_then_impl(std::move(*this), std::forward<F>(f));
1325
  }
1326
  template <class F>
1327
  constexpr auto and_then(F &&f) const & -> decltype(and_then_impl(
1328
      std::declval<expected const &>(), std::forward<F>(f))) {
1329
    return and_then_impl(*this, std::forward<F>(f));
1330
  }
1331
1332
#ifndef TL_EXPECTED_NO_CONSTRR
1333
  template <class F>
1334
  constexpr auto and_then(F &&f) const && -> decltype(and_then_impl(
1335
      std::declval<expected const &&>(), std::forward<F>(f))) {
1336
    return and_then_impl(std::move(*this), std::forward<F>(f));
1337
  }
1338
#endif
1339
#endif
1340
1341
#if defined(TL_EXPECTED_CXX14) && !defined(TL_EXPECTED_GCC49) &&               \
1342
    !defined(TL_EXPECTED_GCC54) && !defined(TL_EXPECTED_GCC55)
1343
  template <class F> TL_EXPECTED_11_CONSTEXPR auto map(F &&f) & {
1344
    return expected_map_impl(*this, std::forward<F>(f));
1345
  }
1346
  template <class F> TL_EXPECTED_11_CONSTEXPR auto map(F &&f) && {
1347
    return expected_map_impl(std::move(*this), std::forward<F>(f));
1348
  }
1349
  template <class F> constexpr auto map(F &&f) const & {
1350
    return expected_map_impl(*this, std::forward<F>(f));
1351
  }
1352
  template <class F> constexpr auto map(F &&f) const && {
1353
    return expected_map_impl(std::move(*this), std::forward<F>(f));
1354
  }
1355
#else
1356
  template <class F>
1357
  TL_EXPECTED_11_CONSTEXPR decltype(expected_map_impl(
1358
      std::declval<expected &>(), std::declval<F &&>()))
1359
  map(F &&f) & {
1360
    return expected_map_impl(*this, std::forward<F>(f));
1361
  }
1362
  template <class F>
1363
  TL_EXPECTED_11_CONSTEXPR decltype(expected_map_impl(std::declval<expected>(),
1364
                                                      std::declval<F &&>()))
1365
  map(F &&f) && {
1366
    return expected_map_impl(std::move(*this), std::forward<F>(f));
1367
  }
1368
  template <class F>
1369
  constexpr decltype(expected_map_impl(std::declval<const expected &>(),
1370
                                       std::declval<F &&>()))
1371
  map(F &&f) const & {
1372
    return expected_map_impl(*this, std::forward<F>(f));
1373
  }
1374
1375
#ifndef TL_EXPECTED_NO_CONSTRR
1376
  template <class F>
1377
  constexpr decltype(expected_map_impl(std::declval<const expected &&>(),
1378
                                       std::declval<F &&>()))
1379
  map(F &&f) const && {
1380
    return expected_map_impl(std::move(*this), std::forward<F>(f));
1381
  }
1382
#endif
1383
#endif
1384
1385
#if defined(TL_EXPECTED_CXX14) && !defined(TL_EXPECTED_GCC49) &&               \
1386
    !defined(TL_EXPECTED_GCC54) && !defined(TL_EXPECTED_GCC55)
1387
  template <class F> TL_EXPECTED_11_CONSTEXPR auto transform(F &&f) & {
1388
    return expected_map_impl(*this, std::forward<F>(f));
1389
  }
1390
  template <class F> TL_EXPECTED_11_CONSTEXPR auto transform(F &&f) && {
1391
    return expected_map_impl(std::move(*this), std::forward<F>(f));
1392
  }
1393
  template <class F> constexpr auto transform(F &&f) const & {
1394
    return expected_map_impl(*this, std::forward<F>(f));
1395
  }
1396
  template <class F> constexpr auto transform(F &&f) const && {
1397
    return expected_map_impl(std::move(*this), std::forward<F>(f));
1398
  }
1399
#else
1400
  template <class F>
1401
  TL_EXPECTED_11_CONSTEXPR decltype(expected_map_impl(
1402
      std::declval<expected &>(), std::declval<F &&>()))
1403
  transform(F &&f) & {
1404
    return expected_map_impl(*this, std::forward<F>(f));
1405
  }
1406
  template <class F>
1407
  TL_EXPECTED_11_CONSTEXPR decltype(expected_map_impl(std::declval<expected>(),
1408
                                                      std::declval<F &&>()))
1409
  transform(F &&f) && {
1410
    return expected_map_impl(std::move(*this), std::forward<F>(f));
1411
  }
1412
  template <class F>
1413
  constexpr decltype(expected_map_impl(std::declval<const expected &>(),
1414
                                       std::declval<F &&>()))
1415
  transform(F &&f) const & {
1416
    return expected_map_impl(*this, std::forward<F>(f));
1417
  }
1418
1419
#ifndef TL_EXPECTED_NO_CONSTRR
1420
  template <class F>
1421
  constexpr decltype(expected_map_impl(std::declval<const expected &&>(),
1422
                                       std::declval<F &&>()))
1423
  transform(F &&f) const && {
1424
    return expected_map_impl(std::move(*this), std::forward<F>(f));
1425
  }
1426
#endif
1427
#endif
1428
1429
#if defined(TL_EXPECTED_CXX14) && !defined(TL_EXPECTED_GCC49) &&               \
1430
    !defined(TL_EXPECTED_GCC54) && !defined(TL_EXPECTED_GCC55)
1431
  template <class F> TL_EXPECTED_11_CONSTEXPR auto map_error(F &&f) & {
1432
    return map_error_impl(*this, std::forward<F>(f));
1433
  }
1434
  template <class F> TL_EXPECTED_11_CONSTEXPR auto map_error(F &&f) && {
1435
    return map_error_impl(std::move(*this), std::forward<F>(f));
1436
  }
1437
  template <class F> constexpr auto map_error(F &&f) const & {
1438
    return map_error_impl(*this, std::forward<F>(f));
1439
  }
1440
  template <class F> constexpr auto map_error(F &&f) const && {
1441
    return map_error_impl(std::move(*this), std::forward<F>(f));
1442
  }
1443
#else
1444
  template <class F>
1445
  TL_EXPECTED_11_CONSTEXPR decltype(map_error_impl(std::declval<expected &>(),
1446
                                                   std::declval<F &&>()))
1447
  map_error(F &&f) & {
1448
    return map_error_impl(*this, std::forward<F>(f));
1449
  }
1450
  template <class F>
1451
  TL_EXPECTED_11_CONSTEXPR decltype(map_error_impl(std::declval<expected &&>(),
1452
                                                   std::declval<F &&>()))
1453
  map_error(F &&f) && {
1454
    return map_error_impl(std::move(*this), std::forward<F>(f));
1455
  }
1456
  template <class F>
1457
  constexpr decltype(map_error_impl(std::declval<const expected &>(),
1458
                                    std::declval<F &&>()))
1459
  map_error(F &&f) const & {
1460
    return map_error_impl(*this, std::forward<F>(f));
1461
  }
1462
1463
#ifndef TL_EXPECTED_NO_CONSTRR
1464
  template <class F>
1465
  constexpr decltype(map_error_impl(std::declval<const expected &&>(),
1466
                                    std::declval<F &&>()))
1467
  map_error(F &&f) const && {
1468
    return map_error_impl(std::move(*this), std::forward<F>(f));
1469
  }
1470
#endif
1471
#endif
1472
#if defined(TL_EXPECTED_CXX14) && !defined(TL_EXPECTED_GCC49) &&               \
1473
    !defined(TL_EXPECTED_GCC54) && !defined(TL_EXPECTED_GCC55)
1474
  template <class F> TL_EXPECTED_11_CONSTEXPR auto transform_error(F &&f) & {
1475
    return map_error_impl(*this, std::forward<F>(f));
1476
  }
1477
  template <class F> TL_EXPECTED_11_CONSTEXPR auto transform_error(F &&f) && {
1478
    return map_error_impl(std::move(*this), std::forward<F>(f));
1479
  }
1480
  template <class F> constexpr auto transform_error(F &&f) const & {
1481
    return map_error_impl(*this, std::forward<F>(f));
1482
  }
1483
  template <class F> constexpr auto transform_error(F &&f) const && {
1484
    return map_error_impl(std::move(*this), std::forward<F>(f));
1485
  }
1486
#else
1487
  template <class F>
1488
  TL_EXPECTED_11_CONSTEXPR decltype(map_error_impl(std::declval<expected &>(),
1489
                                                   std::declval<F &&>()))
1490
  transform_error(F &&f) & {
1491
    return map_error_impl(*this, std::forward<F>(f));
1492
  }
1493
  template <class F>
1494
  TL_EXPECTED_11_CONSTEXPR decltype(map_error_impl(std::declval<expected &&>(),
1495
                                                   std::declval<F &&>()))
1496
  transform_error(F &&f) && {
1497
    return map_error_impl(std::move(*this), std::forward<F>(f));
1498
  }
1499
  template <class F>
1500
  constexpr decltype(map_error_impl(std::declval<const expected &>(),
1501
                                    std::declval<F &&>()))
1502
  transform_error(F &&f) const & {
1503
    return map_error_impl(*this, std::forward<F>(f));
1504
  }
1505
1506
#ifndef TL_EXPECTED_NO_CONSTRR
1507
  template <class F>
1508
  constexpr decltype(map_error_impl(std::declval<const expected &&>(),
1509
                                    std::declval<F &&>()))
1510
  transform_error(F &&f) const && {
1511
    return map_error_impl(std::move(*this), std::forward<F>(f));
1512
  }
1513
#endif
1514
#endif
1515
  template <class F> expected TL_EXPECTED_11_CONSTEXPR or_else(F &&f) & {
1516
    return or_else_impl(*this, std::forward<F>(f));
1517
  }
1518
1519
  template <class F> expected TL_EXPECTED_11_CONSTEXPR or_else(F &&f) && {
1520
    return or_else_impl(std::move(*this), std::forward<F>(f));
1521
  }
1522
1523
  template <class F> expected constexpr or_else(F &&f) const & {
1524
    return or_else_impl(*this, std::forward<F>(f));
1525
  }
1526
1527
#ifndef TL_EXPECTED_NO_CONSTRR
1528
  template <class F> expected constexpr or_else(F &&f) const && {
1529
    return or_else_impl(std::move(*this), std::forward<F>(f));
1530
  }
1531
#endif
1532
  constexpr expected() = default;
1533
  constexpr expected(const expected &rhs) = default;
1534
  constexpr expected(expected &&rhs) = default;
1535
  expected &operator=(const expected &rhs) = default;
1536
  expected &operator=(expected &&rhs) = default;
1537
1538
  template <class... Args,
1539
            detail::enable_if_t<std::is_constructible<T, Args &&...>::value> * =
1540
                nullptr>
1541
  constexpr expected(in_place_t, Args &&...args)
1542
      : impl_base(in_place, std::forward<Args>(args)...),
1543
3
        ctor_base(detail::default_constructor_tag{}) {}
_ZN2tl8expectedISt7variantIJSt10shared_ptrIN5doris10segment_v212idx_query_v213ConjunctionOpEES2_INS5_13DisjunctionOpEES2_INS5_12BooleanQueryEES2_INS5_9TermQueryEES2_INS5_12RoaringQueryEEEENS3_6StatusEEC2IJSF_ELPv0EEENS_10in_place_tEDpOT_
Line
Count
Source
1543
1
        ctor_base(detail::default_constructor_tag{}) {}
_ZN2tl8expectedISt7variantIJSt10shared_ptrIN5doris10segment_v212idx_query_v213ConjunctionOpEES2_INS5_13DisjunctionOpEES2_INS5_12BooleanQueryEES2_INS5_9TermQueryEES2_INS5_12RoaringQueryEEEENS3_6StatusEEC2IJSD_ELPv0EEENS_10in_place_tEDpOT_
Line
Count
Source
1543
2
        ctor_base(detail::default_constructor_tag{}) {}
1544
1545
  template <class U, class... Args,
1546
            detail::enable_if_t<std::is_constructible<
1547
                T, std::initializer_list<U> &, Args &&...>::value> * = nullptr>
1548
  constexpr expected(in_place_t, std::initializer_list<U> il, Args &&...args)
1549
      : impl_base(in_place, il, std::forward<Args>(args)...),
1550
        ctor_base(detail::default_constructor_tag{}) {}
1551
1552
  template <class G = E,
1553
            detail::enable_if_t<std::is_constructible<E, const G &>::value> * =
1554
                nullptr,
1555
            detail::enable_if_t<!std::is_convertible<const G &, E>::value> * =
1556
                nullptr>
1557
  explicit constexpr expected(const unexpected<G> &e)
1558
      : impl_base(unexpect, e.value()),
1559
        ctor_base(detail::default_constructor_tag{}) {}
1560
1561
  template <
1562
      class G = E,
1563
      detail::enable_if_t<std::is_constructible<E, const G &>::value> * =
1564
          nullptr,
1565
      detail::enable_if_t<std::is_convertible<const G &, E>::value> * = nullptr>
1566
  constexpr expected(unexpected<G> const &e)
1567
      : impl_base(unexpect, e.value()),
1568
        ctor_base(detail::default_constructor_tag{}) {}
1569
1570
  template <
1571
      class G = E,
1572
      detail::enable_if_t<std::is_constructible<E, G &&>::value> * = nullptr,
1573
      detail::enable_if_t<!std::is_convertible<G &&, E>::value> * = nullptr>
1574
  explicit constexpr expected(unexpected<G> &&e) noexcept(
1575
      std::is_nothrow_constructible<E, G &&>::value)
1576
      : impl_base(unexpect, std::move(e.value())),
1577
        ctor_base(detail::default_constructor_tag{}) {}
1578
1579
  template <
1580
      class G = E,
1581
      detail::enable_if_t<std::is_constructible<E, G &&>::value> * = nullptr,
1582
      detail::enable_if_t<std::is_convertible<G &&, E>::value> * = nullptr>
1583
  constexpr expected(unexpected<G> &&e) noexcept(
1584
      std::is_nothrow_constructible<E, G &&>::value)
1585
      : impl_base(unexpect, std::move(e.value())),
1586
0
        ctor_base(detail::default_constructor_tag{}) {}
1587
1588
  template <class... Args,
1589
            detail::enable_if_t<std::is_constructible<E, Args &&...>::value> * =
1590
                nullptr>
1591
  constexpr explicit expected(unexpect_t, Args &&...args)
1592
      : impl_base(unexpect, std::forward<Args>(args)...),
1593
        ctor_base(detail::default_constructor_tag{}) {}
1594
1595
  template <class U, class... Args,
1596
            detail::enable_if_t<std::is_constructible<
1597
                E, std::initializer_list<U> &, Args &&...>::value> * = nullptr>
1598
  constexpr explicit expected(unexpect_t, std::initializer_list<U> il,
1599
                              Args &&...args)
1600
      : impl_base(unexpect, il, std::forward<Args>(args)...),
1601
        ctor_base(detail::default_constructor_tag{}) {}
1602
1603
  template <class U, class G,
1604
            detail::enable_if_t<!(std::is_convertible<U const &, T>::value &&
1605
                                  std::is_convertible<G const &, E>::value)> * =
1606
                nullptr,
1607
            detail::expected_enable_from_other<T, E, U, G, const U &, const G &>
1608
                * = nullptr>
1609
  explicit TL_EXPECTED_11_CONSTEXPR expected(const expected<U, G> &rhs)
1610
      : ctor_base(detail::default_constructor_tag{}) {
1611
    if (rhs.has_value()) {
1612
      this->construct(*rhs);
1613
    } else {
1614
      this->construct_error(rhs.error());
1615
    }
1616
  }
1617
1618
  template <class U, class G,
1619
            detail::enable_if_t<(std::is_convertible<U const &, T>::value &&
1620
                                 std::is_convertible<G const &, E>::value)> * =
1621
                nullptr,
1622
            detail::expected_enable_from_other<T, E, U, G, const U &, const G &>
1623
                * = nullptr>
1624
  TL_EXPECTED_11_CONSTEXPR expected(const expected<U, G> &rhs)
1625
      : ctor_base(detail::default_constructor_tag{}) {
1626
    if (rhs.has_value()) {
1627
      this->construct(*rhs);
1628
    } else {
1629
      this->construct_error(rhs.error());
1630
    }
1631
  }
1632
1633
  template <
1634
      class U, class G,
1635
      detail::enable_if_t<!(std::is_convertible<U &&, T>::value &&
1636
                            std::is_convertible<G &&, E>::value)> * = nullptr,
1637
      detail::expected_enable_from_other<T, E, U, G, U &&, G &&> * = nullptr>
1638
  explicit TL_EXPECTED_11_CONSTEXPR expected(expected<U, G> &&rhs)
1639
      : ctor_base(detail::default_constructor_tag{}) {
1640
    if (rhs.has_value()) {
1641
      this->construct(std::move(*rhs));
1642
    } else {
1643
      this->construct_error(std::move(rhs.error()));
1644
    }
1645
  }
1646
1647
  template <
1648
      class U, class G,
1649
      detail::enable_if_t<(std::is_convertible<U &&, T>::value &&
1650
                           std::is_convertible<G &&, E>::value)> * = nullptr,
1651
      detail::expected_enable_from_other<T, E, U, G, U &&, G &&> * = nullptr>
1652
  TL_EXPECTED_11_CONSTEXPR expected(expected<U, G> &&rhs)
1653
      : ctor_base(detail::default_constructor_tag{}) {
1654
    if (rhs.has_value()) {
1655
      this->construct(std::move(*rhs));
1656
    } else {
1657
      this->construct_error(std::move(rhs.error()));
1658
    }
1659
  }
1660
1661
  template <
1662
      class U = T,
1663
      detail::enable_if_t<!std::is_convertible<U &&, T>::value> * = nullptr,
1664
      detail::expected_enable_forward_value<T, E, U> * = nullptr>
1665
  explicit TL_EXPECTED_MSVC2015_CONSTEXPR expected(U &&v)
1666
      : expected(in_place, std::forward<U>(v)) {}
1667
1668
  template <
1669
      class U = T,
1670
      detail::enable_if_t<std::is_convertible<U &&, T>::value> * = nullptr,
1671
      detail::expected_enable_forward_value<T, E, U> * = nullptr>
1672
  TL_EXPECTED_MSVC2015_CONSTEXPR expected(U &&v)
1673
3
      : expected(in_place, std::forward<U>(v)) {}
_ZN2tl8expectedISt7variantIJSt10shared_ptrIN5doris10segment_v212idx_query_v213ConjunctionOpEES2_INS5_13DisjunctionOpEES2_INS5_12BooleanQueryEES2_INS5_9TermQueryEES2_INS5_12RoaringQueryEEEENS3_6StatusEEC2ISF_LPv0ELSK_0EEEOT_
Line
Count
Source
1673
1
      : expected(in_place, std::forward<U>(v)) {}
_ZN2tl8expectedISt7variantIJSt10shared_ptrIN5doris10segment_v212idx_query_v213ConjunctionOpEES2_INS5_13DisjunctionOpEES2_INS5_12BooleanQueryEES2_INS5_9TermQueryEES2_INS5_12RoaringQueryEEEENS3_6StatusEEC2ISD_LPv0ELSK_0EEEOT_
Line
Count
Source
1673
2
      : expected(in_place, std::forward<U>(v)) {}
1674
1675
  template <
1676
      class U = T, class G = T,
1677
      detail::enable_if_t<std::is_nothrow_constructible<T, U &&>::value> * =
1678
          nullptr,
1679
      detail::enable_if_t<!std::is_void<G>::value> * = nullptr,
1680
      detail::enable_if_t<
1681
          (!std::is_same<expected<T, E>, detail::decay_t<U>>::value &&
1682
           !detail::conjunction<std::is_scalar<T>,
1683
                                std::is_same<T, detail::decay_t<U>>>::value &&
1684
           std::is_constructible<T, U>::value &&
1685
           std::is_assignable<G &, U>::value &&
1686
           std::is_nothrow_move_constructible<E>::value)> * = nullptr>
1687
  expected &operator=(U &&v) {
1688
    if (has_value()) {
1689
      val() = std::forward<U>(v);
1690
    } else {
1691
      err().~unexpected<E>();
1692
      ::new (valptr()) T(std::forward<U>(v));
1693
      this->m_has_val = true;
1694
    }
1695
1696
    return *this;
1697
  }
1698
1699
  template <
1700
      class U = T, class G = T,
1701
      detail::enable_if_t<!std::is_nothrow_constructible<T, U &&>::value> * =
1702
          nullptr,
1703
      detail::enable_if_t<!std::is_void<U>::value> * = nullptr,
1704
      detail::enable_if_t<
1705
          (!std::is_same<expected<T, E>, detail::decay_t<U>>::value &&
1706
           !detail::conjunction<std::is_scalar<T>,
1707
                                std::is_same<T, detail::decay_t<U>>>::value &&
1708
           std::is_constructible<T, U>::value &&
1709
           std::is_assignable<G &, U>::value &&
1710
           std::is_nothrow_move_constructible<E>::value)> * = nullptr>
1711
  expected &operator=(U &&v) {
1712
    if (has_value()) {
1713
      val() = std::forward<U>(v);
1714
    } else {
1715
      auto tmp = std::move(err());
1716
      err().~unexpected<E>();
1717
1718
#ifdef TL_EXPECTED_EXCEPTIONS_ENABLED
1719
      try {
1720
        ::new (valptr()) T(std::forward<U>(v));
1721
        this->m_has_val = true;
1722
      } catch (...) {
1723
        err() = std::move(tmp);
1724
        throw;
1725
      }
1726
#else
1727
      ::new (valptr()) T(std::forward<U>(v));
1728
      this->m_has_val = true;
1729
#endif
1730
    }
1731
1732
    return *this;
1733
  }
1734
1735
  template <class G = E,
1736
            detail::enable_if_t<std::is_nothrow_copy_constructible<G>::value &&
1737
                                std::is_assignable<G &, G>::value> * = nullptr>
1738
  expected &operator=(const unexpected<G> &rhs) {
1739
    if (!has_value()) {
1740
      err() = rhs;
1741
    } else {
1742
      this->destroy_val();
1743
      ::new (errptr()) unexpected<E>(rhs);
1744
      this->m_has_val = false;
1745
    }
1746
1747
    return *this;
1748
  }
1749
1750
  template <class G = E,
1751
            detail::enable_if_t<std::is_nothrow_move_constructible<G>::value &&
1752
                                std::is_move_assignable<G>::value> * = nullptr>
1753
  expected &operator=(unexpected<G> &&rhs) noexcept {
1754
    if (!has_value()) {
1755
      err() = std::move(rhs);
1756
    } else {
1757
      this->destroy_val();
1758
      ::new (errptr()) unexpected<E>(std::move(rhs));
1759
      this->m_has_val = false;
1760
    }
1761
1762
    return *this;
1763
  }
1764
1765
  template <class... Args, detail::enable_if_t<std::is_nothrow_constructible<
1766
                               T, Args &&...>::value> * = nullptr>
1767
  void emplace(Args &&...args) {
1768
    if (has_value()) {
1769
      val().~T();
1770
    } else {
1771
      err().~unexpected<E>();
1772
      this->m_has_val = true;
1773
    }
1774
    ::new (valptr()) T(std::forward<Args>(args)...);
1775
  }
1776
1777
  template <class... Args, detail::enable_if_t<!std::is_nothrow_constructible<
1778
                               T, Args &&...>::value> * = nullptr>
1779
  void emplace(Args &&...args) {
1780
    if (has_value()) {
1781
      val().~T();
1782
      ::new (valptr()) T(std::forward<Args>(args)...);
1783
    } else {
1784
      auto tmp = std::move(err());
1785
      err().~unexpected<E>();
1786
1787
#ifdef TL_EXPECTED_EXCEPTIONS_ENABLED
1788
      try {
1789
        ::new (valptr()) T(std::forward<Args>(args)...);
1790
        this->m_has_val = true;
1791
      } catch (...) {
1792
        err() = std::move(tmp);
1793
        throw;
1794
      }
1795
#else
1796
      ::new (valptr()) T(std::forward<Args>(args)...);
1797
      this->m_has_val = true;
1798
#endif
1799
    }
1800
  }
1801
1802
  template <class U, class... Args,
1803
            detail::enable_if_t<std::is_nothrow_constructible<
1804
                T, std::initializer_list<U> &, Args &&...>::value> * = nullptr>
1805
  void emplace(std::initializer_list<U> il, Args &&...args) {
1806
    if (has_value()) {
1807
      T t(il, std::forward<Args>(args)...);
1808
      val() = std::move(t);
1809
    } else {
1810
      err().~unexpected<E>();
1811
      ::new (valptr()) T(il, std::forward<Args>(args)...);
1812
      this->m_has_val = true;
1813
    }
1814
  }
1815
1816
  template <class U, class... Args,
1817
            detail::enable_if_t<!std::is_nothrow_constructible<
1818
                T, std::initializer_list<U> &, Args &&...>::value> * = nullptr>
1819
  void emplace(std::initializer_list<U> il, Args &&...args) {
1820
    if (has_value()) {
1821
      T t(il, std::forward<Args>(args)...);
1822
      val() = std::move(t);
1823
    } else {
1824
      auto tmp = std::move(err());
1825
      err().~unexpected<E>();
1826
1827
#ifdef TL_EXPECTED_EXCEPTIONS_ENABLED
1828
      try {
1829
        ::new (valptr()) T(il, std::forward<Args>(args)...);
1830
        this->m_has_val = true;
1831
      } catch (...) {
1832
        err() = std::move(tmp);
1833
        throw;
1834
      }
1835
#else
1836
      ::new (valptr()) T(il, std::forward<Args>(args)...);
1837
      this->m_has_val = true;
1838
#endif
1839
    }
1840
  }
1841
1842
private:
1843
  using t_is_void = std::true_type;
1844
  using t_is_not_void = std::false_type;
1845
  using t_is_nothrow_move_constructible = std::true_type;
1846
  using move_constructing_t_can_throw = std::false_type;
1847
  using e_is_nothrow_move_constructible = std::true_type;
1848
  using move_constructing_e_can_throw = std::false_type;
1849
1850
  void swap_where_both_have_value(expected & /*rhs*/, t_is_void) noexcept {
1851
    // swapping void is a no-op
1852
  }
1853
1854
  void swap_where_both_have_value(expected &rhs, t_is_not_void) {
1855
    using std::swap;
1856
    swap(val(), rhs.val());
1857
  }
1858
1859
  void swap_where_only_one_has_value(expected &rhs, t_is_void) noexcept(
1860
      std::is_nothrow_move_constructible<E>::value) {
1861
    ::new (errptr()) unexpected_type(std::move(rhs.err()));
1862
    rhs.err().~unexpected_type();
1863
    std::swap(this->m_has_val, rhs.m_has_val);
1864
  }
1865
1866
  void swap_where_only_one_has_value(expected &rhs, t_is_not_void) {
1867
    swap_where_only_one_has_value_and_t_is_not_void(
1868
        rhs, typename std::is_nothrow_move_constructible<T>::type{},
1869
        typename std::is_nothrow_move_constructible<E>::type{});
1870
  }
1871
1872
  void swap_where_only_one_has_value_and_t_is_not_void(
1873
      expected &rhs, t_is_nothrow_move_constructible,
1874
      e_is_nothrow_move_constructible) noexcept {
1875
    auto temp = std::move(val());
1876
    val().~T();
1877
    ::new (errptr()) unexpected_type(std::move(rhs.err()));
1878
    rhs.err().~unexpected_type();
1879
    ::new (rhs.valptr()) T(std::move(temp));
1880
    std::swap(this->m_has_val, rhs.m_has_val);
1881
  }
1882
1883
  void swap_where_only_one_has_value_and_t_is_not_void(
1884
      expected &rhs, t_is_nothrow_move_constructible,
1885
      move_constructing_e_can_throw) {
1886
    auto temp = std::move(val());
1887
    val().~T();
1888
#ifdef TL_EXPECTED_EXCEPTIONS_ENABLED
1889
    try {
1890
      ::new (errptr()) unexpected_type(std::move(rhs.err()));
1891
      rhs.err().~unexpected_type();
1892
      ::new (rhs.valptr()) T(std::move(temp));
1893
      std::swap(this->m_has_val, rhs.m_has_val);
1894
    } catch (...) {
1895
      val() = std::move(temp);
1896
      throw;
1897
    }
1898
#else
1899
    ::new (errptr()) unexpected_type(std::move(rhs.err()));
1900
    rhs.err().~unexpected_type();
1901
    ::new (rhs.valptr()) T(std::move(temp));
1902
    std::swap(this->m_has_val, rhs.m_has_val);
1903
#endif
1904
  }
1905
1906
  void swap_where_only_one_has_value_and_t_is_not_void(
1907
      expected &rhs, move_constructing_t_can_throw,
1908
      e_is_nothrow_move_constructible) {
1909
    auto temp = std::move(rhs.err());
1910
    rhs.err().~unexpected_type();
1911
#ifdef TL_EXPECTED_EXCEPTIONS_ENABLED
1912
    try {
1913
      ::new (rhs.valptr()) T(std::move(val()));
1914
      val().~T();
1915
      ::new (errptr()) unexpected_type(std::move(temp));
1916
      std::swap(this->m_has_val, rhs.m_has_val);
1917
    } catch (...) {
1918
      rhs.err() = std::move(temp);
1919
      throw;
1920
    }
1921
#else
1922
    ::new (rhs.valptr()) T(std::move(val()));
1923
    val().~T();
1924
    ::new (errptr()) unexpected_type(std::move(temp));
1925
    std::swap(this->m_has_val, rhs.m_has_val);
1926
#endif
1927
  }
1928
1929
public:
1930
  template <class OT = T, class OE = E>
1931
  detail::enable_if_t<detail::is_swappable<OT>::value &&
1932
                      detail::is_swappable<OE>::value &&
1933
                      (std::is_nothrow_move_constructible<OT>::value ||
1934
                       std::is_nothrow_move_constructible<OE>::value)>
1935
  swap(expected &rhs) noexcept(
1936
      std::is_nothrow_move_constructible<T>::value
1937
          &&detail::is_nothrow_swappable<T>::value
1938
              &&std::is_nothrow_move_constructible<E>::value
1939
                  &&detail::is_nothrow_swappable<E>::value) {
1940
    if (has_value() && rhs.has_value()) {
1941
      swap_where_both_have_value(rhs, typename std::is_void<T>::type{});
1942
    } else if (!has_value() && rhs.has_value()) {
1943
      rhs.swap(*this);
1944
    } else if (has_value()) {
1945
      swap_where_only_one_has_value(rhs, typename std::is_void<T>::type{});
1946
    } else {
1947
      using std::swap;
1948
      swap(err(), rhs.err());
1949
    }
1950
  }
1951
1952
  constexpr const T *operator->() const {
1953
    TL_ASSERT(has_value());
1954
    return valptr();
1955
  }
1956
4
  TL_EXPECTED_11_CONSTEXPR T *operator->() {
1957
4
    TL_ASSERT(has_value());
1958
0
    return valptr();
1959
4
  }
1960
1961
  template <class U = T,
1962
            detail::enable_if_t<!std::is_void<U>::value> * = nullptr>
1963
  constexpr const U &operator*() const & {
1964
    TL_ASSERT(has_value());
1965
    return val();
1966
  }
1967
  template <class U = T,
1968
            detail::enable_if_t<!std::is_void<U>::value> * = nullptr>
1969
  TL_EXPECTED_11_CONSTEXPR U &operator*() & {
1970
    TL_ASSERT(has_value());
1971
    return val();
1972
  }
1973
  template <class U = T,
1974
            detail::enable_if_t<!std::is_void<U>::value> * = nullptr>
1975
  constexpr const U &&operator*() const && {
1976
    TL_ASSERT(has_value());
1977
    return std::move(val());
1978
  }
1979
  template <class U = T,
1980
            detail::enable_if_t<!std::is_void<U>::value> * = nullptr>
1981
  TL_EXPECTED_11_CONSTEXPR U &&operator*() && {
1982
    TL_ASSERT(has_value());
1983
    return std::move(val());
1984
  }
1985
1986
11.8k
  constexpr bool has_value() const noexcept { return this->m_has_val; }
_ZNK2tl8expectedISt10shared_ptrIN5doris2io12S3FileSystemEENS2_6StatusEE9has_valueEv
Line
Count
Source
1986
4
  constexpr bool has_value() const noexcept { return this->m_has_val; }
_ZNK2tl8expectedISt10unique_ptrIN5doris12RowsetWriterESt14default_deleteIS3_EENS2_6StatusEE9has_valueEv
Line
Count
Source
1986
944
  constexpr bool has_value() const noexcept { return this->m_has_val; }
_ZNK2tl8expectedISt10unique_ptrIN5doris10segment_v219DorisCompoundReaderESt14default_deleteIS4_EENS2_6StatusEE9has_valueEv
Line
Count
Source
1986
372
  constexpr bool has_value() const noexcept { return this->m_has_val; }
_ZNK2tl8expectedISt7variantIJSt10shared_ptrIN6lucene6search13IndexSearcherEES2_INS3_4util3bkd10bkd_readerEEEEN5doris6StatusEE9has_valueEv
Line
Count
Source
1986
24
  constexpr bool has_value() const noexcept { return this->m_has_val; }
_ZNK2tl8expectedINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEN5doris6StatusEE9has_valueEv
Line
Count
Source
1986
10.0k
  constexpr bool has_value() const noexcept { return this->m_has_val; }
_ZNK2tl8expectedISt3mapISt4pairIlNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEESt10shared_ptrIN6lucene5store9DirectoryEESt4lessIS9_ESaIS2_IKS9_SE_EEEN5doris6StatusEE9has_valueEv
Line
Count
Source
1986
46
  constexpr bool has_value() const noexcept { return this->m_has_val; }
_ZNK2tl8expectedISt7variantIJSt10shared_ptrIN5doris10segment_v212idx_query_v213ConjunctionOpEES2_INS5_13DisjunctionOpEES2_INS5_12BooleanQueryEES2_INS5_9TermQueryEES2_INS5_12RoaringQueryEEEENS3_6StatusEE9has_valueEv
Line
Count
Source
1986
14
  constexpr bool has_value() const noexcept { return this->m_has_val; }
_ZNK2tl8expectedISt10shared_ptrIN5doris10segment_v216DorisFSDirectoryEENS2_6StatusEE9has_valueEv
Line
Count
Source
1986
422
  constexpr bool has_value() const noexcept { return this->m_has_val; }
1987
  constexpr explicit operator bool() const noexcept { return this->m_has_val; }
1988
1989
  template <class U = T,
1990
            detail::enable_if_t<!std::is_void<U>::value> * = nullptr>
1991
53
  TL_EXPECTED_11_CONSTEXPR const U &value() const & {
1992
53
    if (!has_value())
1993
0
      detail::throw_exception(bad_expected_access<E>(err().value()));
1994
53
    return val();
1995
53
  }
_ZNKR2tl8expectedISt10unique_ptrIN5doris12RowsetWriterESt14default_deleteIS3_EENS2_6StatusEE5valueIS6_LPv0EEERKT_v
Line
Count
Source
1991
5
  TL_EXPECTED_11_CONSTEXPR const U &value() const & {
1992
5
    if (!has_value())
1993
0
      detail::throw_exception(bad_expected_access<E>(err().value()));
1994
5
    return val();
1995
5
  }
_ZNKR2tl8expectedINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEN5doris6StatusEE5valueIS6_LPv0EEERKT_v
Line
Count
Source
1991
25
  TL_EXPECTED_11_CONSTEXPR const U &value() const & {
1992
25
    if (!has_value())
1993
0
      detail::throw_exception(bad_expected_access<E>(err().value()));
1994
25
    return val();
1995
25
  }
_ZNKR2tl8expectedISt3mapISt4pairIlNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEESt10shared_ptrIN6lucene5store9DirectoryEESt4lessIS9_ESaIS2_IKS9_SE_EEEN5doris6StatusEE5valueISK_LPv0EEERKT_v
Line
Count
Source
1991
23
  TL_EXPECTED_11_CONSTEXPR const U &value() const & {
1992
23
    if (!has_value())
1993
0
      detail::throw_exception(bad_expected_access<E>(err().value()));
1994
23
    return val();
1995
23
  }
1996
  template <class U = T,
1997
            detail::enable_if_t<!std::is_void<U>::value> * = nullptr>
1998
164
  TL_EXPECTED_11_CONSTEXPR U &value() & {
1999
164
    if (!has_value())
2000
0
      detail::throw_exception(bad_expected_access<E>(err().value()));
2001
164
    return val();
2002
164
  }
_ZNR2tl8expectedISt10shared_ptrIN5doris2io12S3FileSystemEENS2_6StatusEE5valueIS5_LPv0EEERT_v
Line
Count
Source
1998
2
  TL_EXPECTED_11_CONSTEXPR U &value() & {
1999
2
    if (!has_value())
2000
0
      detail::throw_exception(bad_expected_access<E>(err().value()));
2001
2
    return val();
2002
2
  }
_ZNR2tl8expectedISt10unique_ptrIN5doris10segment_v219DorisCompoundReaderESt14default_deleteIS4_EENS2_6StatusEE5valueIS7_LPv0EEERT_v
Line
Count
Source
1998
144
  TL_EXPECTED_11_CONSTEXPR U &value() & {
1999
144
    if (!has_value())
2000
0
      detail::throw_exception(bad_expected_access<E>(err().value()));
2001
144
    return val();
2002
144
  }
_ZNR2tl8expectedISt7variantIJSt10shared_ptrIN6lucene6search13IndexSearcherEES2_INS3_4util3bkd10bkd_readerEEEEN5doris6StatusEE5valueISB_LPv0EEERT_v
Line
Count
Source
1998
12
  TL_EXPECTED_11_CONSTEXPR U &value() & {
1999
12
    if (!has_value())
2000
0
      detail::throw_exception(bad_expected_access<E>(err().value()));
2001
12
    return val();
2002
12
  }
_ZNR2tl8expectedISt10shared_ptrIN5doris10segment_v216DorisFSDirectoryEENS2_6StatusEE5valueIS5_LPv0EEERT_v
Line
Count
Source
1998
6
  TL_EXPECTED_11_CONSTEXPR U &value() & {
1999
6
    if (!has_value())
2000
0
      detail::throw_exception(bad_expected_access<E>(err().value()));
2001
6
    return val();
2002
6
  }
2003
  template <class U = T,
2004
            detail::enable_if_t<!std::is_void<U>::value> * = nullptr>
2005
  TL_EXPECTED_11_CONSTEXPR const U &&value() const && {
2006
    if (!has_value())
2007
      detail::throw_exception(bad_expected_access<E>(std::move(err()).value()));
2008
    return std::move(val());
2009
  }
2010
  template <class U = T,
2011
            detail::enable_if_t<!std::is_void<U>::value> * = nullptr>
2012
474
  TL_EXPECTED_11_CONSTEXPR U &&value() && {
2013
474
    if (!has_value())
2014
0
      detail::throw_exception(bad_expected_access<E>(std::move(err()).value()));
2015
474
    return std::move(val());
2016
474
  }
_ZNO2tl8expectedISt10unique_ptrIN5doris12RowsetWriterESt14default_deleteIS3_EENS2_6StatusEE5valueIS6_LPv0EEEOT_v
Line
Count
Source
2012
467
  TL_EXPECTED_11_CONSTEXPR U &&value() && {
2013
467
    if (!has_value())
2014
0
      detail::throw_exception(bad_expected_access<E>(std::move(err()).value()));
2015
467
    return std::move(val());
2016
467
  }
_ZNO2tl8expectedISt7variantIJSt10shared_ptrIN5doris10segment_v212idx_query_v213ConjunctionOpEES2_INS5_13DisjunctionOpEES2_INS5_12BooleanQueryEES2_INS5_9TermQueryEES2_INS5_12RoaringQueryEEEENS3_6StatusEE5valueISG_LPv0EEEOT_v
Line
Count
Source
2012
7
  TL_EXPECTED_11_CONSTEXPR U &&value() && {
2013
7
    if (!has_value())
2014
0
      detail::throw_exception(bad_expected_access<E>(std::move(err()).value()));
2015
7
    return std::move(val());
2016
7
  }
2017
2018
0
  constexpr const E &error() const & {
2019
0
    TL_ASSERT(!has_value());
2020
0
    return err().value();
2021
0
  }
2022
0
  TL_EXPECTED_11_CONSTEXPR E &error() & {
2023
0
    TL_ASSERT(!has_value());
2024
0
    return err().value();
2025
0
  }
Unexecuted instantiation: _ZNR2tl8expectedISt10shared_ptrIN5doris2io12S3FileSystemEENS2_6StatusEE5errorEv
Unexecuted instantiation: _ZNR2tl8expectedISt10unique_ptrIN5doris12RowsetWriterESt14default_deleteIS3_EENS2_6StatusEE5errorEv
2026
  constexpr const E &&error() const && {
2027
    TL_ASSERT(!has_value());
2028
    return std::move(err().value());
2029
  }
2030
0
  TL_EXPECTED_11_CONSTEXPR E &&error() && {
2031
0
    TL_ASSERT(!has_value());
2032
0
    return std::move(err().value());
2033
0
  }
2034
2035
  template <class U> constexpr T value_or(U &&v) const & {
2036
    static_assert(std::is_copy_constructible<T>::value &&
2037
                      std::is_convertible<U &&, T>::value,
2038
                  "T must be copy-constructible and convertible to from U&&");
2039
    return bool(*this) ? **this : static_cast<T>(std::forward<U>(v));
2040
  }
2041
  template <class U> TL_EXPECTED_11_CONSTEXPR T value_or(U &&v) && {
2042
    static_assert(std::is_move_constructible<T>::value &&
2043
                      std::is_convertible<U &&, T>::value,
2044
                  "T must be move-constructible and convertible to from U&&");
2045
    return bool(*this) ? std::move(**this) : static_cast<T>(std::forward<U>(v));
2046
  }
2047
};
2048
2049
namespace detail {
2050
template <class Exp> using exp_t = typename detail::decay_t<Exp>::value_type;
2051
template <class Exp> using err_t = typename detail::decay_t<Exp>::error_type;
2052
template <class Exp, class Ret> using ret_t = expected<Ret, err_t<Exp>>;
2053
2054
#ifdef TL_EXPECTED_CXX14
2055
template <class Exp, class F,
2056
          detail::enable_if_t<!std::is_void<exp_t<Exp>>::value> * = nullptr,
2057
          class Ret = decltype(detail::invoke(std::declval<F>(),
2058
                                              *std::declval<Exp>()))>
2059
constexpr auto and_then_impl(Exp &&exp, F &&f) {
2060
  static_assert(detail::is_expected<Ret>::value, "F must return an expected");
2061
2062
  return exp.has_value()
2063
             ? detail::invoke(std::forward<F>(f), *std::forward<Exp>(exp))
2064
             : Ret(unexpect, std::forward<Exp>(exp).error());
2065
}
2066
2067
template <class Exp, class F,
2068
          detail::enable_if_t<std::is_void<exp_t<Exp>>::value> * = nullptr,
2069
          class Ret = decltype(detail::invoke(std::declval<F>()))>
2070
constexpr auto and_then_impl(Exp &&exp, F &&f) {
2071
  static_assert(detail::is_expected<Ret>::value, "F must return an expected");
2072
2073
  return exp.has_value() ? detail::invoke(std::forward<F>(f))
2074
                         : Ret(unexpect, std::forward<Exp>(exp).error());
2075
}
2076
#else
2077
template <class> struct TC;
2078
template <class Exp, class F,
2079
          class Ret = decltype(detail::invoke(std::declval<F>(),
2080
                                              *std::declval<Exp>())),
2081
          detail::enable_if_t<!std::is_void<exp_t<Exp>>::value> * = nullptr>
2082
auto and_then_impl(Exp &&exp, F &&f) -> Ret {
2083
  static_assert(detail::is_expected<Ret>::value, "F must return an expected");
2084
2085
  return exp.has_value()
2086
             ? detail::invoke(std::forward<F>(f), *std::forward<Exp>(exp))
2087
             : Ret(unexpect, std::forward<Exp>(exp).error());
2088
}
2089
2090
template <class Exp, class F,
2091
          class Ret = decltype(detail::invoke(std::declval<F>())),
2092
          detail::enable_if_t<std::is_void<exp_t<Exp>>::value> * = nullptr>
2093
constexpr auto and_then_impl(Exp &&exp, F &&f) -> Ret {
2094
  static_assert(detail::is_expected<Ret>::value, "F must return an expected");
2095
2096
  return exp.has_value() ? detail::invoke(std::forward<F>(f))
2097
                         : Ret(unexpect, std::forward<Exp>(exp).error());
2098
}
2099
#endif
2100
2101
#ifdef TL_EXPECTED_CXX14
2102
template <class Exp, class F,
2103
          detail::enable_if_t<!std::is_void<exp_t<Exp>>::value> * = nullptr,
2104
          class Ret = decltype(detail::invoke(std::declval<F>(),
2105
                                              *std::declval<Exp>())),
2106
          detail::enable_if_t<!std::is_void<Ret>::value> * = nullptr>
2107
constexpr auto expected_map_impl(Exp &&exp, F &&f) {
2108
  using result = ret_t<Exp, detail::decay_t<Ret>>;
2109
  return exp.has_value() ? result(detail::invoke(std::forward<F>(f),
2110
                                                 *std::forward<Exp>(exp)))
2111
                         : result(unexpect, std::forward<Exp>(exp).error());
2112
}
2113
2114
template <class Exp, class F,
2115
          detail::enable_if_t<!std::is_void<exp_t<Exp>>::value> * = nullptr,
2116
          class Ret = decltype(detail::invoke(std::declval<F>(),
2117
                                              *std::declval<Exp>())),
2118
          detail::enable_if_t<std::is_void<Ret>::value> * = nullptr>
2119
auto expected_map_impl(Exp &&exp, F &&f) {
2120
  using result = expected<void, err_t<Exp>>;
2121
  if (exp.has_value()) {
2122
    detail::invoke(std::forward<F>(f), *std::forward<Exp>(exp));
2123
    return result();
2124
  }
2125
2126
  return result(unexpect, std::forward<Exp>(exp).error());
2127
}
2128
2129
template <class Exp, class F,
2130
          detail::enable_if_t<std::is_void<exp_t<Exp>>::value> * = nullptr,
2131
          class Ret = decltype(detail::invoke(std::declval<F>())),
2132
          detail::enable_if_t<!std::is_void<Ret>::value> * = nullptr>
2133
constexpr auto expected_map_impl(Exp &&exp, F &&f) {
2134
  using result = ret_t<Exp, detail::decay_t<Ret>>;
2135
  return exp.has_value() ? result(detail::invoke(std::forward<F>(f)))
2136
                         : result(unexpect, std::forward<Exp>(exp).error());
2137
}
2138
2139
template <class Exp, class F,
2140
          detail::enable_if_t<std::is_void<exp_t<Exp>>::value> * = nullptr,
2141
          class Ret = decltype(detail::invoke(std::declval<F>())),
2142
          detail::enable_if_t<std::is_void<Ret>::value> * = nullptr>
2143
auto expected_map_impl(Exp &&exp, F &&f) {
2144
  using result = expected<void, err_t<Exp>>;
2145
  if (exp.has_value()) {
2146
    detail::invoke(std::forward<F>(f));
2147
    return result();
2148
  }
2149
2150
  return result(unexpect, std::forward<Exp>(exp).error());
2151
}
2152
#else
2153
template <class Exp, class F,
2154
          detail::enable_if_t<!std::is_void<exp_t<Exp>>::value> * = nullptr,
2155
          class Ret = decltype(detail::invoke(std::declval<F>(),
2156
                                              *std::declval<Exp>())),
2157
          detail::enable_if_t<!std::is_void<Ret>::value> * = nullptr>
2158
2159
constexpr auto expected_map_impl(Exp &&exp, F &&f)
2160
    -> ret_t<Exp, detail::decay_t<Ret>> {
2161
  using result = ret_t<Exp, detail::decay_t<Ret>>;
2162
2163
  return exp.has_value() ? result(detail::invoke(std::forward<F>(f),
2164
                                                 *std::forward<Exp>(exp)))
2165
                         : result(unexpect, std::forward<Exp>(exp).error());
2166
}
2167
2168
template <class Exp, class F,
2169
          detail::enable_if_t<!std::is_void<exp_t<Exp>>::value> * = nullptr,
2170
          class Ret = decltype(detail::invoke(std::declval<F>(),
2171
                                              *std::declval<Exp>())),
2172
          detail::enable_if_t<std::is_void<Ret>::value> * = nullptr>
2173
2174
auto expected_map_impl(Exp &&exp, F &&f) -> expected<void, err_t<Exp>> {
2175
  if (exp.has_value()) {
2176
    detail::invoke(std::forward<F>(f), *std::forward<Exp>(exp));
2177
    return {};
2178
  }
2179
2180
  return unexpected<err_t<Exp>>(std::forward<Exp>(exp).error());
2181
}
2182
2183
template <class Exp, class F,
2184
          detail::enable_if_t<std::is_void<exp_t<Exp>>::value> * = nullptr,
2185
          class Ret = decltype(detail::invoke(std::declval<F>())),
2186
          detail::enable_if_t<!std::is_void<Ret>::value> * = nullptr>
2187
2188
constexpr auto expected_map_impl(Exp &&exp, F &&f)
2189
    -> ret_t<Exp, detail::decay_t<Ret>> {
2190
  using result = ret_t<Exp, detail::decay_t<Ret>>;
2191
2192
  return exp.has_value() ? result(detail::invoke(std::forward<F>(f)))
2193
                         : result(unexpect, std::forward<Exp>(exp).error());
2194
}
2195
2196
template <class Exp, class F,
2197
          detail::enable_if_t<std::is_void<exp_t<Exp>>::value> * = nullptr,
2198
          class Ret = decltype(detail::invoke(std::declval<F>())),
2199
          detail::enable_if_t<std::is_void<Ret>::value> * = nullptr>
2200
2201
auto expected_map_impl(Exp &&exp, F &&f) -> expected<void, err_t<Exp>> {
2202
  if (exp.has_value()) {
2203
    detail::invoke(std::forward<F>(f));
2204
    return {};
2205
  }
2206
2207
  return unexpected<err_t<Exp>>(std::forward<Exp>(exp).error());
2208
}
2209
#endif
2210
2211
#if defined(TL_EXPECTED_CXX14) && !defined(TL_EXPECTED_GCC49) &&               \
2212
    !defined(TL_EXPECTED_GCC54) && !defined(TL_EXPECTED_GCC55)
2213
template <class Exp, class F,
2214
          detail::enable_if_t<!std::is_void<exp_t<Exp>>::value> * = nullptr,
2215
          class Ret = decltype(detail::invoke(std::declval<F>(),
2216
                                              std::declval<Exp>().error())),
2217
          detail::enable_if_t<!std::is_void<Ret>::value> * = nullptr>
2218
constexpr auto map_error_impl(Exp &&exp, F &&f) {
2219
  using result = expected<exp_t<Exp>, detail::decay_t<Ret>>;
2220
  return exp.has_value()
2221
             ? result(*std::forward<Exp>(exp))
2222
             : result(unexpect, detail::invoke(std::forward<F>(f),
2223
                                               std::forward<Exp>(exp).error()));
2224
}
2225
template <class Exp, class F,
2226
          detail::enable_if_t<!std::is_void<exp_t<Exp>>::value> * = nullptr,
2227
          class Ret = decltype(detail::invoke(std::declval<F>(),
2228
                                              std::declval<Exp>().error())),
2229
          detail::enable_if_t<std::is_void<Ret>::value> * = nullptr>
2230
auto map_error_impl(Exp &&exp, F &&f) {
2231
  using result = expected<exp_t<Exp>, monostate>;
2232
  if (exp.has_value()) {
2233
    return result(*std::forward<Exp>(exp));
2234
  }
2235
2236
  detail::invoke(std::forward<F>(f), std::forward<Exp>(exp).error());
2237
  return result(unexpect, monostate{});
2238
}
2239
template <class Exp, class F,
2240
          detail::enable_if_t<std::is_void<exp_t<Exp>>::value> * = nullptr,
2241
          class Ret = decltype(detail::invoke(std::declval<F>(),
2242
                                              std::declval<Exp>().error())),
2243
          detail::enable_if_t<!std::is_void<Ret>::value> * = nullptr>
2244
constexpr auto map_error_impl(Exp &&exp, F &&f) {
2245
  using result = expected<exp_t<Exp>, detail::decay_t<Ret>>;
2246
  return exp.has_value()
2247
             ? result()
2248
             : result(unexpect, detail::invoke(std::forward<F>(f),
2249
                                               std::forward<Exp>(exp).error()));
2250
}
2251
template <class Exp, class F,
2252
          detail::enable_if_t<std::is_void<exp_t<Exp>>::value> * = nullptr,
2253
          class Ret = decltype(detail::invoke(std::declval<F>(),
2254
                                              std::declval<Exp>().error())),
2255
          detail::enable_if_t<std::is_void<Ret>::value> * = nullptr>
2256
auto map_error_impl(Exp &&exp, F &&f) {
2257
  using result = expected<exp_t<Exp>, monostate>;
2258
  if (exp.has_value()) {
2259
    return result();
2260
  }
2261
2262
  detail::invoke(std::forward<F>(f), std::forward<Exp>(exp).error());
2263
  return result(unexpect, monostate{});
2264
}
2265
#else
2266
template <class Exp, class F,
2267
          detail::enable_if_t<!std::is_void<exp_t<Exp>>::value> * = nullptr,
2268
          class Ret = decltype(detail::invoke(std::declval<F>(),
2269
                                              std::declval<Exp>().error())),
2270
          detail::enable_if_t<!std::is_void<Ret>::value> * = nullptr>
2271
constexpr auto map_error_impl(Exp &&exp, F &&f)
2272
    -> expected<exp_t<Exp>, detail::decay_t<Ret>> {
2273
  using result = expected<exp_t<Exp>, detail::decay_t<Ret>>;
2274
2275
  return exp.has_value()
2276
             ? result(*std::forward<Exp>(exp))
2277
             : result(unexpect, detail::invoke(std::forward<F>(f),
2278
                                               std::forward<Exp>(exp).error()));
2279
}
2280
2281
template <class Exp, class F,
2282
          detail::enable_if_t<!std::is_void<exp_t<Exp>>::value> * = nullptr,
2283
          class Ret = decltype(detail::invoke(std::declval<F>(),
2284
                                              std::declval<Exp>().error())),
2285
          detail::enable_if_t<std::is_void<Ret>::value> * = nullptr>
2286
auto map_error_impl(Exp &&exp, F &&f) -> expected<exp_t<Exp>, monostate> {
2287
  using result = expected<exp_t<Exp>, monostate>;
2288
  if (exp.has_value()) {
2289
    return result(*std::forward<Exp>(exp));
2290
  }
2291
2292
  detail::invoke(std::forward<F>(f), std::forward<Exp>(exp).error());
2293
  return result(unexpect, monostate{});
2294
}
2295
2296
template <class Exp, class F,
2297
          detail::enable_if_t<std::is_void<exp_t<Exp>>::value> * = nullptr,
2298
          class Ret = decltype(detail::invoke(std::declval<F>(),
2299
                                              std::declval<Exp>().error())),
2300
          detail::enable_if_t<!std::is_void<Ret>::value> * = nullptr>
2301
constexpr auto map_error_impl(Exp &&exp, F &&f)
2302
    -> expected<exp_t<Exp>, detail::decay_t<Ret>> {
2303
  using result = expected<exp_t<Exp>, detail::decay_t<Ret>>;
2304
2305
  return exp.has_value()
2306
             ? result()
2307
             : result(unexpect, detail::invoke(std::forward<F>(f),
2308
                                               std::forward<Exp>(exp).error()));
2309
}
2310
2311
template <class Exp, class F,
2312
          detail::enable_if_t<std::is_void<exp_t<Exp>>::value> * = nullptr,
2313
          class Ret = decltype(detail::invoke(std::declval<F>(),
2314
                                              std::declval<Exp>().error())),
2315
          detail::enable_if_t<std::is_void<Ret>::value> * = nullptr>
2316
auto map_error_impl(Exp &&exp, F &&f) -> expected<exp_t<Exp>, monostate> {
2317
  using result = expected<exp_t<Exp>, monostate>;
2318
  if (exp.has_value()) {
2319
    return result();
2320
  }
2321
2322
  detail::invoke(std::forward<F>(f), std::forward<Exp>(exp).error());
2323
  return result(unexpect, monostate{});
2324
}
2325
#endif
2326
2327
#ifdef TL_EXPECTED_CXX14
2328
template <class Exp, class F,
2329
          class Ret = decltype(detail::invoke(std::declval<F>(),
2330
                                              std::declval<Exp>().error())),
2331
          detail::enable_if_t<!std::is_void<Ret>::value> * = nullptr>
2332
constexpr auto or_else_impl(Exp &&exp, F &&f) {
2333
  static_assert(detail::is_expected<Ret>::value, "F must return an expected");
2334
  return exp.has_value() ? std::forward<Exp>(exp)
2335
                         : detail::invoke(std::forward<F>(f),
2336
                                          std::forward<Exp>(exp).error());
2337
}
2338
2339
template <class Exp, class F,
2340
          class Ret = decltype(detail::invoke(std::declval<F>(),
2341
                                              std::declval<Exp>().error())),
2342
          detail::enable_if_t<std::is_void<Ret>::value> * = nullptr>
2343
detail::decay_t<Exp> or_else_impl(Exp &&exp, F &&f) {
2344
  return exp.has_value() ? std::forward<Exp>(exp)
2345
                         : (detail::invoke(std::forward<F>(f),
2346
                                           std::forward<Exp>(exp).error()),
2347
                            std::forward<Exp>(exp));
2348
}
2349
#else
2350
template <class Exp, class F,
2351
          class Ret = decltype(detail::invoke(std::declval<F>(),
2352
                                              std::declval<Exp>().error())),
2353
          detail::enable_if_t<!std::is_void<Ret>::value> * = nullptr>
2354
auto or_else_impl(Exp &&exp, F &&f) -> Ret {
2355
  static_assert(detail::is_expected<Ret>::value, "F must return an expected");
2356
  return exp.has_value() ? std::forward<Exp>(exp)
2357
                         : detail::invoke(std::forward<F>(f),
2358
                                          std::forward<Exp>(exp).error());
2359
}
2360
2361
template <class Exp, class F,
2362
          class Ret = decltype(detail::invoke(std::declval<F>(),
2363
                                              std::declval<Exp>().error())),
2364
          detail::enable_if_t<std::is_void<Ret>::value> * = nullptr>
2365
detail::decay_t<Exp> or_else_impl(Exp &&exp, F &&f) {
2366
  return exp.has_value() ? std::forward<Exp>(exp)
2367
                         : (detail::invoke(std::forward<F>(f),
2368
                                           std::forward<Exp>(exp).error()),
2369
                            std::forward<Exp>(exp));
2370
}
2371
#endif
2372
} // namespace detail
2373
2374
template <class T, class E, class U, class F>
2375
constexpr bool operator==(const expected<T, E> &lhs,
2376
                          const expected<U, F> &rhs) {
2377
  return (lhs.has_value() != rhs.has_value())
2378
             ? false
2379
             : (!lhs.has_value() ? lhs.error() == rhs.error() : *lhs == *rhs);
2380
}
2381
template <class T, class E, class U, class F>
2382
constexpr bool operator!=(const expected<T, E> &lhs,
2383
                          const expected<U, F> &rhs) {
2384
  return (lhs.has_value() != rhs.has_value())
2385
             ? true
2386
             : (!lhs.has_value() ? lhs.error() != rhs.error() : *lhs != *rhs);
2387
}
2388
template <class E, class F>
2389
constexpr bool operator==(const expected<void, E> &lhs,
2390
                          const expected<void, F> &rhs) {
2391
  return (lhs.has_value() != rhs.has_value())
2392
             ? false
2393
             : (!lhs.has_value() ? lhs.error() == rhs.error() : true);
2394
}
2395
template <class E, class F>
2396
constexpr bool operator!=(const expected<void, E> &lhs,
2397
                          const expected<void, F> &rhs) {
2398
  return (lhs.has_value() != rhs.has_value())
2399
             ? true
2400
             : (!lhs.has_value() ? lhs.error() == rhs.error() : false);
2401
}
2402
2403
template <class T, class E, class U>
2404
constexpr bool operator==(const expected<T, E> &x, const U &v) {
2405
  return x.has_value() ? *x == v : false;
2406
}
2407
template <class T, class E, class U>
2408
constexpr bool operator==(const U &v, const expected<T, E> &x) {
2409
  return x.has_value() ? *x == v : false;
2410
}
2411
template <class T, class E, class U>
2412
constexpr bool operator!=(const expected<T, E> &x, const U &v) {
2413
  return x.has_value() ? *x != v : true;
2414
}
2415
template <class T, class E, class U>
2416
constexpr bool operator!=(const U &v, const expected<T, E> &x) {
2417
  return x.has_value() ? *x != v : true;
2418
}
2419
2420
template <class T, class E>
2421
constexpr bool operator==(const expected<T, E> &x, const unexpected<E> &e) {
2422
  return x.has_value() ? false : x.error() == e.value();
2423
}
2424
template <class T, class E>
2425
constexpr bool operator==(const unexpected<E> &e, const expected<T, E> &x) {
2426
  return x.has_value() ? false : x.error() == e.value();
2427
}
2428
template <class T, class E>
2429
constexpr bool operator!=(const expected<T, E> &x, const unexpected<E> &e) {
2430
  return x.has_value() ? true : x.error() != e.value();
2431
}
2432
template <class T, class E>
2433
constexpr bool operator!=(const unexpected<E> &e, const expected<T, E> &x) {
2434
  return x.has_value() ? true : x.error() != e.value();
2435
}
2436
2437
template <class T, class E,
2438
          detail::enable_if_t<(std::is_void<T>::value ||
2439
                               std::is_move_constructible<T>::value) &&
2440
                              detail::is_swappable<T>::value &&
2441
                              std::is_move_constructible<E>::value &&
2442
                              detail::is_swappable<E>::value> * = nullptr>
2443
void swap(expected<T, E> &lhs,
2444
          expected<T, E> &rhs) noexcept(noexcept(lhs.swap(rhs))) {
2445
  lhs.swap(rhs);
2446
}
2447
} // namespace tl
2448
2449
#endif
2450
// NOLINTEND
2451
// clang-format on