11#include <Sawyer/Optional.h> 
   13#include <boost/lexical_cast.hpp> 
   14#include <boost/variant.hpp> 
   21template <
class F, 
class... Args>
 
   25    static auto test(U* p) -> 
decltype((*p)(std::declval<Args>()...), void(), std::true_type());
 
   27    static auto test(...) -> 
decltype(std::false_type());
 
   29    static constexpr bool value = 
decltype(test<F>(0))::value;
 
 
   42#ifdef SAWYER_HAVE_BOOST_SERIALIZATION 
   44    friend class boost::serialization::access;
 
   47    void serialize(S &s, 
const unsigned ) {
 
   48        s & BOOST_SERIALIZATION_NVP(ok_);
 
   52#ifdef SAWYER_HAVE_CEREAL 
   54    friend class cereal::access;
 
   56    template<
class Archive>
 
   57    void CEREAL_SERIALIZE_FUNCTION_NAME(Archive &archive) {
 
   58        archive(cereal::make_nvp(
"ok", ok_));
 
   70    explicit Ok(
const Value &ok)
 
 
 
  101    using Value = std::string;
 
  106#ifdef SAWYER_HAVE_BOOST_SERIALIZATION 
  108    friend class boost::serialization::access;
 
  111    void serialize(S &s, 
const unsigned ) {
 
  112        s & BOOST_SERIALIZATION_NVP(ok_);
 
  116#ifdef SAWYER_HAVE_CEREAL 
  118    friend class cereal::access;
 
  120    template<
class Archive>
 
  121    void CEREAL_SERIALIZE_FUNCTION_NAME(Archive &archive) {
 
  122        archive(cereal::make_nvp(
"ok", ok_));
 
  129    explicit Ok(
const Value &s)
 
 
  161inline Ok<std::string> 
makeOk(
const char *s) {
 
  162    return Ok<std::string>(std::string(s));
 
  164inline Ok<std::string> 
makeOk(
char *s) {
 
  165    return Ok<std::string>(std::string(s));
 
  177#ifdef SAWYER_HAVE_BOOST_SERIALIZATION 
  179    friend class boost::serialization::access;
 
  182    void serialize(S &s, 
const unsigned ) {
 
  183        s & BOOST_SERIALIZATION_NVP(error_);
 
  187#ifdef SAWYER_HAVE_CEREAL 
  189    friend class cereal::access;
 
  191    template<
class Archive>
 
  192    void CEREAL_SERIALIZE_FUNCTION_NAME(Archive &archive) {
 
  193        archive(cereal::make_nvp(
"error", error_));
 
  202        : error_(other.error_) {}
 
 
  212        error_ = other.error_;
 
 
 
  236    using Value = std::string;
 
  241#ifdef SAWYER_HAVE_BOOST_SERIALIZATION 
  243    friend class boost::serialization::access;
 
  246    void serialize(S &s, 
const unsigned ) {
 
  247        s & BOOST_SERIALIZATION_NVP(error_);
 
  251#ifdef SAWYER_HAVE_CEREAL 
  253    friend class cereal::access;
 
  255    template<
class Archive>
 
  256    void CEREAL_SERIALIZE_FUNCTION_NAME(Archive &archive) {
 
  257        archive(cereal::make_nvp(
"error", error_));
 
  266        : error_(other.error_) {}
 
 
  276        error_ = other.error_;
 
 
 
  306inline Error<std::string> 
makeError(
const char *s) {
 
  307    return Error<std::string>(std::string(s));
 
  309inline Error<std::string> 
makeError(
char *s) {
 
  310    return Error<std::string>(std::string(s));
 
  314template<
class T, 
class E>
 
  318    using ErrorValue = E;
 
  323    boost::variant<Ok<T>, 
Error<E>> result_;
 
  325#ifdef SAWYER_HAVE_BOOST_SERIALIZATION 
  327    friend class boost::serialization::access;
 
  330    void save(S &s, 
const unsigned )
 const {
 
  331        s <<boost::serialization::make_nvp(
"isOk", 
isOk());
 
  333            s <<boost::serialization::make_nvp(
"ok", 
unwrap());
 
  335            s <<boost::serialization::make_nvp(
"error", 
unwrapError());
 
  340    void load(S &s, 
const unsigned ) {
 
  342        s >>boost::serialization::make_nvp(
"isOk", 
isOk);
 
  345            s >>boost::serialization::make_nvp(
"ok", 
ok);
 
  349            s >>boost::serialization::make_nvp(
"error", 
error);
 
  354    BOOST_SERIALIZATION_SPLIT_MEMBER();
 
  357#ifdef SAWYER_HAVE_CEREAL 
  359    friend class cereal::access;
 
  361    template<
class Archive>
 
  362    void CEREAL_SAVE_FUNCTION_NAME(Archive &archive)
 const {
 
  363        archive(cereal::make_nvp(
"isOk", 
isOk()));
 
  365            archive(cereal::make_nvp(
"ok", 
unwrap()));
 
  371    template<
class Archive>
 
  372    void CEREAL_LOAD_FUNCTION_NAME(Archive &archive) {
 
  374        archive(cereal::make_nvp(
"isOk", 
isOk));
 
  377            archive(cereal::make_nvp(
"ok", 
ok));
 
  381            archive(cereal::make_nvp(
"error", 
error));
 
  388    template<
class U = T>
 
  392    template<
class F = E>
 
  397    template<
class U = T>
 
  404    template<
class F = E>
 
  411    template<
class U = T>
 
  413        return isOk() && *this->
ok() == *
ok;
 
 
  417    template<
class U = T>
 
  419        return !(*
this == 
ok);
 
 
  423    template<
class F = E>
 
  429    template<
class F = E>
 
  431        return !(*
this == 
error);
 
 
  435    template<
class U, 
class F>
 
  437        return ((
isOk() && other.
isOk() && *
ok() == *other.
ok()) ||
 
 
  442    template<
class U, 
class F>
 
  444        return !(*
this == other);
 
 
  451        return result_.which() == 0;
 
 
  453    explicit operator bool()
 const {
 
 
  468            return *boost::get<OkType>(result_);
 
 
  481            return *boost::get<ErrorType>(result_);
 
 
  488    const T& 
expect(
const std::string &mesg)
 const {
 
  490            return *boost::get<OkType>(result_);
 
  492            throw std::runtime_error(mesg);
 
 
  502        return expect(
"result is not okay");
 
 
  526    typename std::enable_if<is_invocable<Fn, ErrorValue>::value, 
const Result>::type
 
  541            return boost::get<OkType>(result_);
 
 
  557    template<
class Exception = E>
 
  562            throw Exception(*
error());
 
 
  567    template<
class Exception = E>
 
  581    typename std::enable_if<is_invocable<Fn, OkValue>::value, 
const Result>::type
 
  598            return boost::get<ErrorType>(result_);
 
 
  607            throw std::runtime_error(mesg);
 
  609            return *boost::get<ErrorType>(result_);
 
 
  638    Optional<Result<typename T::Value, E>>
 
  652    Result<typename OkValue::OkValue, E> flatten()
 const {
 
  691    template <
typename F>
 
 
Error(const Error &other)
Copy constructor.
 
Error & operator=(const Value &error)
Assignment.
 
const Value & operator*() const
Dereference to obtain error.
 
Error & operator=(const Error &other)
Assignment.
 
const Value * operator->() const
Dereference to obtain pointer to error.
 
Error(const Value &error)
Construct from a value.
 
const Value & operator*() const
Dereference to obtain error.
 
const Value * operator->() const
Dereference to obtain pointer to error.
 
Error(const E &error)
Construct from a value.
 
Error & operator=(const Value &error)
Assignment.
 
Error(const Error &other)
Copy constructor.
 
Error & operator=(const Error &other)
Assignment.
 
Ok & operator=(const Ok &other)
Assignment.
 
const Value * operator->() const
Dereference to obtain pointer.
 
Ok & operator=(const Value &ok)
Assignment.
 
Ok(const Ok &other)
Copy constructor.
 
const Value & operator*() const
Dereference to obtain value.
 
Ok(const Value &ok)
Construct from an value.
 
Holds a value or nothing.
 
Result containing a value or an error.
 
const T orElse(const T &dflt) const
Returns the contained Ok value or a provided default.
 
bool operator==(const Result< U, F > &other) const
Test whether this result is equal to the other result.
 
bool operator!=(const Ok< U > &ok) const
Test whether this result does not have the specified Ok value.
 
const T & expect(const std::string &mesg) const
Returns the success value or throws an exception.
 
const Sawyer::Optional< T > ok() const
Convert to Optional<T>.
 
bool contains(const U &value) const
Returns true if this result contains the specified okay value.
 
std::enable_if< is_invocable< Fn, ErrorValue >::value, constResult >::type orElse(Fn fn) const
Returns the contained Ok value, or calls a function.
 
const E & expectError(const std::string &mesg) const
Returns the error value or throws an exception.
 
bool operator==(const Ok< U > &ok) const
Test whether this result has the specified Ok value.
 
Result & operator=(const Error< F > &error)
Assign an Error value to this result.
 
const E & unwrapError() const
Returns the error value or throws an exception.
 
const T & orDefault() const
Returns the okay value or a default constructed value.
 
const T & operator*() const
Returns the success value or throws an exception.
 
const Result< U, E > andThen(const Result< U, E > &other) const
Returns this error or the other result.
 
const T & unwrap() const
Returns the success value or throws an exception.
 
const Result & assignTo(U &out) const
Conditionally save a value.
 
bool operator==(const Error< F > &error) const
Test whether this result has the specified Error value.
 
const Sawyer::Optional< E > error() const
Convert to Optional<E>.
 
const Result< T, F > orElse(const Result< T, F > &other) const
Returns this value or the other result.
 
bool isError() const
Returns true if the result is an error.
 
bool operator!=(const Result< U, F > &other) const
Test whether this result is unequal to the other result.
 
Result & assignTo(U &out) const
Conditionally save a value.
 
const T * operator->() const
Returns a pointer to the success value, or thows an exception.
 
bool operator!=(const Error< F > &error) const
Test whether this result does not have the specified Error value.
 
const T & orThrow(const Exception &e) const
Returns the value or throws an exception constructed from the specified value.
 
Result & operator=(const Ok< U > &ok)
Assign an Ok value to this result.
 
bool containsError(const F &error) const
Returns true if this result contains the specified error value.
 
std::enable_if< is_invocable< Fn, OkValue >::value, constResult >::type andThen(Fn fn) const
Returns the contained Error value, or calls a function.
 
auto fmap(F &&f) -> Result< decltype(f(unwrap())), E >
Conditionally apply a functor f to the contents of a Result.
 
const T & orThrow() const
Returns the value or throws an exception.
 
bool isOk() const
Returns true if the result is okay.
 
Error< T > makeError(const T &value)
Conventient way to constructo an Error value before C++17.
 
Ok< T > makeOk(const T &value)
Conventient way to constructo an Ok value before C++17.