1 ////////////////////////////////////////////////////////////////////////////////
3 // Copyright (c) 2007 by Rich Sposato
4 // Permission to use, copy, modify, distribute and sell this software for any
5 // purpose is hereby granted without fee, provided that the above copyright
6 // notice appear in all copies and that both that copyright notice and this
7 // permission notice appear in supporting documentation.
8 // The author makes no representations about the
9 // suitability of this software for any purpose. It is provided "as is"
10 // without express or implied warranty.
11 ////////////////////////////////////////////////////////////////////////////////
13 #ifndef LOKI_CHECK_RETURN_INC_
14 #define LOKI_CHECK_RETURN_INC_
27 // ----------------------------------------------------------------------------
29 ////////////////////////////////////////////////////////////////////////////////
30 /// \class CheckReturn
33 /// C++ provides no mechanism within the language itself to force code to
34 /// check the return value from a function call. This simple class provides
35 /// a mechanism by which programmers can force calling functions to check the
36 /// return value. Or at least make them consciously choose to disregard the
37 /// return value. If the calling function fails to use or store the return
38 /// value, the destructor calls the OnError policy.
40 /// \par Template Parameters
41 /// CheckReturn has two template parameters, Value and OnError.
42 /// - Value is the return type from the function. CheckReturn stores a copy of
43 /// it rather than a reference or pointer since return value could be local to
44 /// a function. CheckReturn works best when the return type is a built-in
45 /// primitive (bool, int, etc...) a pointer, or an enum (such as an error
46 /// condition enum). It can work with other types that have cheap copy
48 /// - OnError is a policy class indicating how to handle the situation when a
49 /// caller does not check or copy the returned value. Loki provides some
50 /// policy classs and you may also write your own. For example, you can write
51 /// a policy to create a message box when the function ignores the return value.
52 /// That would quickly tell you places where code ignores the function call.
53 /// If your write your own, you only need a templated class or struct with a
54 /// public function named "run" that accepts a reference to a const value.
56 /// @par Provided Policy Classes
57 /// - IgnoreReturnValue Deliberately ignores when the caller ignores the return value.
58 /// - TriggerAssert Asserts in debug builds if the caller ignores the return value.
59 /// - FprintfStderr Prints out an error message if the caller ignores the return value.
60 /// - ThrowTheValue Throws the ignored value as an exception.
61 /// - ThrowLogicError Throws a logic_error exception to indicate a programming error.
62 ////////////////////////////////////////////////////////////////////////////////
66 struct IgnoreReturnValue
68 static void run(const T &)
70 /// Do nothing at all.
77 static void run(const T &value )
84 struct ThrowLogicError
86 static void run( const T & )
88 throw ::std::logic_error( "CheckReturn: return value was not checked.\n" );
95 static void run(const T &)
104 static void run(const T &)
106 fprintf(stderr, "CheckReturn: return value was not checked.\n");
112 template < class Value , template<class> class OnError = TriggerAssert >
117 /// Conversion constructor changes Value type to CheckReturn type.
118 inline CheckReturn( const Value &value ) :
119 m_value( value ), m_checked( false ) {}
121 /// Copy-constructor allows functions to call another function within the
122 /// return statement. The other CheckReturn's m_checked flag is set since
123 /// its duty has been passed to the m_checked flag in this one.
124 inline CheckReturn( const CheckReturn &that ) :
125 m_value( that.m_value ), m_checked( false )
127 that.m_checked = true;
130 /// Destructor checks if return value was used.
131 inline ~CheckReturn( void )
133 // If m_checked is false, then a function failed to check the
134 // return value from a function call.
136 OnError<Value>::run(m_value);
139 /// Conversion operator changes CheckReturn back to Value type.
140 inline operator Value ( void )
147 /// Default constructor not implemented.
150 /// Copy-assignment operator not implemented.
151 CheckReturn &operator = ( const CheckReturn &that );
153 /// Copy of returned value.
156 /// Flag for whether calling function checked return value yet.
157 mutable bool m_checked;
160 // ----------------------------------------------------------------------------
164 #endif // end file guardian