45 lines
		
	
	
		
			1.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			45 lines
		
	
	
		
			1.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
#pragma once
 | 
						|
#include <utility>
 | 
						|
#include <variant>
 | 
						|
 | 
						|
namespace meta
 | 
						|
{
 | 
						|
	// a struct stolen from rust
 | 
						|
	// lets us define a result, or return an error otherwise
 | 
						|
	template<typename Result, typename Error>
 | 
						|
	class result
 | 
						|
		: protected std::variant<Result, Error>
 | 
						|
	{
 | 
						|
	protected:
 | 
						|
		using Base = std::variant<Result, Error>;
 | 
						|
	private:
 | 
						|
		static constexpr auto Success = 0;
 | 
						|
		static constexpr auto Failure = 1;
 | 
						|
		static_assert(std::is_default_constructible_v<Error>, "Error must be default constructible");
 | 
						|
	public:
 | 
						|
		using value_type = Result;
 | 
						|
		using Base::Base;
 | 
						|
		using Base::operator=;
 | 
						|
 | 
						|
		// accessors
 | 
						|
		Result& value();
 | 
						|
		template<typename U, typename = std::enable_if_t<std::is_constructible_v<Result, U>>>
 | 
						|
		Result value_or(U&& result) const;
 | 
						|
		Error& error();
 | 
						|
		const Result& value() const;
 | 
						|
		const Error& error() const;
 | 
						|
 | 
						|
		// monadic operators
 | 
						|
		template<class Fn>              auto map(Fn&& visitor) const;
 | 
						|
		template<class Fn>              auto and_then(Fn&& visitor) const;
 | 
						|
		template<class Fn, class ErrFn> auto and_then(Fn&& visitor, ErrFn&& err_visitor) const;
 | 
						|
		template<class ErrFunc>         auto or_else(ErrFunc&& err_visitor) const;
 | 
						|
 | 
						|
		// operator overloads 
 | 
						|
		explicit operator bool() const;
 | 
						|
		Result& operator*();
 | 
						|
		Result* operator->();
 | 
						|
		const Result& operator*() const;
 | 
						|
		const Result* operator->() const;
 | 
						|
	};
 | 
						|
} |