- #include <system_error> 
- #include <type_traits> 
- #include <new> 
-   
- // #define USE_OUTCOME  
- // #define USE_ERROR 
-   
- // BOOST_NOINLINE ---------------------------------------------// 
- // Macro to use in place of 'inline' to prevent a function to be inlined 
- #if !defined(BOOST_NOINLINE) 
- #  if defined(_MSC_VER) 
- #    define BOOST_NOINLINE __declspec(noinline) 
- #  elif defined(__GNUC__) && __GNUC__ > 3 
-      // Clang also defines __GNUC__ (as 4) 
- #    if defined(__CUDACC__) 
-        // nvcc doesn't always parse __noinline__,  
-        // see: https://s...content-available-to-author-only...t.org/trac/boost/ticket/9392 
- #      define BOOST_NOINLINE __attribute__ ((noinline)) 
- #    else 
- #      define BOOST_NOINLINE __attribute__ ((__noinline__)) 
- #    endif 
- #  else 
- #    define BOOST_NOINLINE 
- #  endif 
- #endif 
-   
- #ifdef USE_OUTCOME 
- #include <boost/outcome/monad.hpp> 
-   
- using namespace BOOST_OUTCOME_V1_NAMESPACE; 
- #else 
-   
- class not_an_error_category_impl : public std::error_category 
- { 
- public: 
-     virtual const char* name() const noexcept { return ""; } 
-     virtual std::string message( int ev ) const { return std::string{}; } 
-     virtual std::error_condition default_error_condition( int ev ) const noexcept { 
-         return std::error_condition( ev, *this ); 
-     } 
- }; 
-   
- not_an_error_category_impl instance; 
-   
- inline const std::error_category& not_an_error_category() 
- { 
-     return instance; 
- } 
-   
- template< typename T > 
- struct result { 
-     typedef typename std::aligned_storage<sizeof( T ), alignof(T)>::type value_store; 
-     value_store value; 
-     std::error_code error; 
-   
-     result( const T& x ) { 
-         error.assign( 0, not_an_error_category() ); 
-         new(&value) T( x ); 
-     } 
-   
-     result( T&& x ) { 
-         error.assign( 0, not_an_error_category() ); 
-         new(&value) T( std::move( x ) ); 
-     } 
-   
-     result( std::error_code x ) : error( x ) { 
-     } 
-   
-     ~result() { 
-         destroy<T>(); 
-     } 
-   
-     result( const result& rhs ) { 
-         copy<T>( rhs ); 
-     } 
-   
-     result( result&& rhs ) { 
-         move<T>( std::move( rhs ) ); 
-     } 
-   
-     explicit operator bool() const { 
-         return (&error.category() == ¬_an_error_category()); 
-     } 
-   
-     T& get() { 
-         return *reinterpret_cast<T*>(&value); 
-     } 
-   
-     template< typename U > 
-     typename std::enable_if<std::is_trivially_destructible<U>::value>::type destroy() {} 
-     template< typename U > 
-     typename std::enable_if<!std::is_trivially_destructible<U>::value>::type destroy() { 
-         if ( *this ) { 
-             get().~T(); 
-         } 
-     } 
-   
-     template< typename U > 
-     typename std::enable_if<std::is_trivially_copyable<U>::value>::type copy( const result<T>& rhs ) { 
-         value = rhs.value; 
-         error = rhs.error; 
-     } 
-     template< typename U > 
-     typename std::enable_if<!std::is_trivially_copyable<U>::value>::type copy( const result<T>& rhs ) { 
-         destroy<T>(); 
-         if ( rhs ) { 
-             new(&value) T( rhs.value ); 
-         } 
-         error = rhs.error; 
-     } 
-   
-     template< typename U > 
-     typename std::enable_if<std::is_trivially_move_constructible<U>::value>::type move( result<T>&& rhs ) { 
-         value = rhs.value; 
-         error = rhs.error; 
-     } 
-     template< typename U > 
-     typename std::enable_if<!std::is_trivially_move_constructible<U>::value>::type move( result<T>&& rhs ) { 
-         destroy<T>(); 
-         if ( rhs ) { 
-             new(&value) T( std::move( rhs.value ) ); 
-         } 
-         error = rhs.error; 
-     } 
- }; 
- #endif 
-   
- BOOST_NOINLINE result<int> bar() 
- { 
- #ifdef USE_ERROR 
-     return std::make_error_code( std::errc::bad_address ); 
- #else 
-     return 1; 
- #endif 
- } 
-   
- int main() 
- { 
-     result<int> _foo = bar(); 
-     int foo = 0; 
-     if ( _foo ) { 
-         foo = _foo.get(); 
-     } 
-     return foo; 
- } 
-