1 /*
2  *  Created by Phil on 02/12/2012.
3  *  Copyright 2012 Two Blue Cubes Ltd. All rights reserved.
4  *
5  *  Distributed under the Boost Software License, Version 1.0. (See accompanying
6  *  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7  */
8 #ifndef TWOBLUECUBES_CATCH_OPTION_HPP_INCLUDED
9 #define TWOBLUECUBES_CATCH_OPTION_HPP_INCLUDED
10 
11 namespace Catch {
12 
13     // An optional type
14     template<typename T>
15     class Option {
16     public:
Option()17         Option() : nullableValue( nullptr ) {}
Option(T const & _value)18         Option( T const& _value )
19         : nullableValue( new( storage ) T( _value ) )
20         {}
Option(Option const & _other)21         Option( Option const& _other )
22         : nullableValue( _other ? new( storage ) T( *_other ) : nullptr )
23         {}
24 
~Option()25         ~Option() {
26             reset();
27         }
28 
operator =(Option const & _other)29         Option& operator= ( Option const& _other ) {
30             if( &_other != this ) {
31                 reset();
32                 if( _other )
33                     nullableValue = new( storage ) T( *_other );
34             }
35             return *this;
36         }
operator =(T const & _value)37         Option& operator = ( T const& _value ) {
38             reset();
39             nullableValue = new( storage ) T( _value );
40             return *this;
41         }
42 
reset()43         void reset() {
44             if( nullableValue )
45                 nullableValue->~T();
46             nullableValue = nullptr;
47         }
48 
operator *()49         T& operator*() { return *nullableValue; }
operator *() const50         T const& operator*() const { return *nullableValue; }
operator ->()51         T* operator->() { return nullableValue; }
operator ->() const52         const T* operator->() const { return nullableValue; }
53 
valueOr(T const & defaultValue) const54         T valueOr( T const& defaultValue ) const {
55             return nullableValue ? *nullableValue : defaultValue;
56         }
57 
some() const58         bool some() const { return nullableValue != nullptr; }
none() const59         bool none() const { return nullableValue == nullptr; }
60 
operator !() const61         bool operator !() const { return nullableValue == nullptr; }
operator bool() const62         explicit operator bool() const {
63             return some();
64         }
65 
66     private:
67         T *nullableValue;
68         alignas(alignof(T)) char storage[sizeof(T)];
69     };
70 
71 } // end namespace Catch
72 
73 #endif // TWOBLUECUBES_CATCH_OPTION_HPP_INCLUDED
74