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 #include "catch_common.h"
12 
13 namespace Catch {
14 
15     // An optional type
16     template<typename T>
17     class Option {
18     public:
Option()19         Option() : nullableValue( CATCH_NULL ) {}
Option(T const & _value)20         Option( T const& _value )
21         : nullableValue( new( storage ) T( _value ) )
22         {}
Option(Option const & _other)23         Option( Option const& _other )
24         : nullableValue( _other ? new( storage ) T( *_other ) : CATCH_NULL )
25         {}
26 
~Option()27         ~Option() {
28             reset();
29         }
30 
operator =(Option const & _other)31         Option& operator= ( Option const& _other ) {
32             if( &_other != this ) {
33                 reset();
34                 if( _other )
35                     nullableValue = new( storage ) T( *_other );
36             }
37             return *this;
38         }
operator =(T const & _value)39         Option& operator = ( T const& _value ) {
40             reset();
41             nullableValue = new( storage ) T( _value );
42             return *this;
43         }
44 
reset()45         void reset() {
46             if( nullableValue )
47                 nullableValue->~T();
48             nullableValue = CATCH_NULL;
49         }
50 
operator *()51         T& operator*() { return *nullableValue; }
operator *() const52         T const& operator*() const { return *nullableValue; }
operator ->()53         T* operator->() { return nullableValue; }
operator ->() const54         const T* operator->() const { return nullableValue; }
55 
valueOr(T const & defaultValue) const56         T valueOr( T const& defaultValue ) const {
57             return nullableValue ? *nullableValue : defaultValue;
58         }
59 
some() const60         bool some() const { return nullableValue != CATCH_NULL; }
none() const61         bool none() const { return nullableValue == CATCH_NULL; }
62 
operator !() const63         bool operator !() const { return nullableValue == CATCH_NULL; }
operator SafeBool::type() const64         operator SafeBool::type() const {
65             return SafeBool::makeSafe( some() );
66         }
67 
68     private:
69         T *nullableValue;
70         union {
71             char storage[sizeof(T)];
72 
73             // These are here to force alignment for the storage
74             long double dummy1;
75             void (*dummy2)();
76             long double dummy3;
77 #ifdef CATCH_CONFIG_CPP11_LONG_LONG
78             long long dummy4;
79 #endif
80         };
81     };
82 
83 } // end namespace Catch
84 
85 #endif // TWOBLUECUBES_CATCH_OPTION_HPP_INCLUDED
86