1 //  (C) Copyright Gennadiy Rozental 2001.
2 //  Distributed under the Boost Software License, Version 1.0.
3 //  (See accompanying file LICENSE_1_0.txt or copy at
4 //  http://www.boost.org/LICENSE_1_0.txt)
5 
6 //  See http://www.boost.org/libs/test for the library home page.
7 //
8 //  File        : $RCSfile$
9 //
10 //  Version     : $Revision$
11 //
12 //  Description : model of actual argument (both typed and abstract interface)
13 // ***************************************************************************
14 
15 #ifndef BOOST_TEST_UTILS_RUNTIME_ARGUMENT_HPP
16 #define BOOST_TEST_UTILS_RUNTIME_ARGUMENT_HPP
17 
18 // Boost.Test Runtime parameters
19 #include <boost/test/utils/runtime/fwd.hpp>
20 #include <boost/test/utils/runtime/errors.hpp>
21 
22 // Boost.Test
23 #include <boost/test/utils/class_properties.hpp>
24 #include <boost/test/utils/rtti.hpp>
25 #include <boost/test/utils/basic_cstring/compare.hpp>
26 #include <boost/test/detail/throw_exception.hpp>
27 
28 // STL
29 #include <cassert>
30 
31 #include <boost/test/detail/suppress_warnings.hpp>
32 
33 namespace boost {
34 namespace runtime {
35 
36 // ************************************************************************** //
37 // **************              runtime::argument               ************** //
38 // ************************************************************************** //
39 
40 class argument {
41 public:
42     // Constructor
argument(rtti::id_t value_type)43     argument( rtti::id_t value_type )
44     : p_value_type( value_type )
45     {}
46 
47     // Destructor
~argument()48     virtual     ~argument()  {}
49 
50     // Public properties
51     rtti::id_t const    p_value_type;
52 };
53 
54 // ************************************************************************** //
55 // **************             runtime::typed_argument          ************** //
56 // ************************************************************************** //
57 
58 template<typename T>
59 class typed_argument : public argument {
60 public:
61     // Constructor
typed_argument(T const & v)62     explicit typed_argument( T const& v )
63     : argument( rtti::type_id<T>() )
64     , p_value( v )
65     {}
66 
67     unit_test::readwrite_property<T>    p_value;
68 };
69 
70 // ************************************************************************** //
71 // **************           runtime::arguments_store          ************** //
72 // ************************************************************************** //
73 
74 class arguments_store {
75 public:
76     typedef std::map<cstring, argument_ptr> storage_type;
77 
78     /// Returns number of arguments in the store; mostly used for testing
size() const79     std::size_t size() const        { return m_arguments.size(); }
80 
81     /// Clears the store for reuse
clear()82     void        clear()             { m_arguments.clear(); }
83 
84     /// Returns true if there is an argument corresponding to the specified parameter name
has(cstring parameter_name) const85     bool        has( cstring parameter_name ) const
86     {
87         return m_arguments.find( parameter_name ) != m_arguments.end();
88     }
89 
90     /// Provides types access to argument value by parameter name
91     template<typename T>
get(cstring parameter_name) const92     T const&    get( cstring parameter_name ) const {
93         return const_cast<arguments_store*>(this)->get<T>( parameter_name );
94     }
95 
96     template<typename T>
get(cstring parameter_name)97     T&          get( cstring parameter_name ) {
98         storage_type::const_iterator found = m_arguments.find( parameter_name );
99         BOOST_TEST_I_ASSRT( found != m_arguments.end(),
100                             access_to_missing_argument()
101                                 << "There is no argument provided for parameter "
102                                 << parameter_name );
103 
104         argument_ptr arg = found->second;
105 
106         BOOST_TEST_I_ASSRT( arg->p_value_type == rtti::type_id<T>(),
107                             arg_type_mismatch()
108                                 << "Access with invalid type for argument corresponding to parameter "
109                                 << parameter_name );
110 
111         return static_cast<typed_argument<T>&>( *arg ).p_value.value;
112     }
113 
114     /// Set's the argument value for specified parameter name
115     template<typename T>
set(cstring parameter_name,T const & value)116     void        set( cstring parameter_name, T const& value )
117     {
118         m_arguments[parameter_name] = argument_ptr( new typed_argument<T>( value ) );
119     }
120 
121 private:
122     // Data members
123     storage_type            m_arguments;
124 };
125 
126 } // namespace runtime
127 } // namespace boost
128 
129 #include <boost/test/detail/enable_warnings.hpp>
130 
131 #endif // BOOST_TEST_UTILS_RUNTIME_ARGUMENT_HPP
132