Result.h
 1  #pragma once
 2  
 3  #include <variant>
 4  
 5  template<typename T>
 6  class Ok
 7  {
 8  public:
 9      explicit constexpr Ok(T value) :
10          value(std::move(value)) {}
11  
12      constexpr T&& get() { return std::move(value); }
13  
14      T value;
15  };
16  
17  template<typename T>
18  class Error
19  {
20  public:
21      explicit constexpr Error(T value) :
22          value(std::move(value)) {}
23  
24      constexpr T&& get() { return std::move(value); }
25  
26      T value;
27  };
28  
29  template<typename OkT, typename ErrT>
30  class Result
31  {
32  public:
33      using VariantT = std::variant<Ok<OkT>, Error<ErrT>>;
34  
35      constexpr Result(Ok<OkT> value) :
36          variant(std::move(value)) 
37      {}
38      
39      constexpr Result(Error<ErrT> value) :
40          variant(std::move(value)) 
41      {}
42  
43      constexpr bool isOk() const { return std::holds_alternative<Ok<OkT>>(variant); }
44      constexpr bool isError() const { return std::holds_alternative<Error<ErrT>>(variant); }
45  
46      constexpr OkT value() const { return std::get<Ok<OkT>>(variant).value; }
47      constexpr ErrT error() const { return std::get<Error<ErrT>>(variant).value; }
48  
49      constexpr OkT&& getValue() { return std::get<Ok<OkT>>(variant).get(); }
50      constexpr ErrT&& getError() { return std::get<Error<ErrT>>(variant).get(); }
51  
52      VariantT variant;
53  };