summaryrefslogtreecommitdiff
path: root/boost/test/utils/runtime/argument.hpp
blob: 879ee96f9f0c665b3dcaac9cee658b2c8b4506b2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
//  (C) Copyright Gennadiy Rozental 2001.
//  Distributed under the Boost Software License, Version 1.0.
//  (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)

//  See http://www.boost.org/libs/test for the library home page.
//
//  File        : $RCSfile$
//
//  Version     : $Revision$
//
//  Description : model of actual argument (both typed and abstract interface)
// ***************************************************************************

#ifndef BOOST_TEST_UTILS_RUNTIME_ARGUMENT_HPP
#define BOOST_TEST_UTILS_RUNTIME_ARGUMENT_HPP

// Boost.Test Runtime parameters
#include <boost/test/utils/runtime/fwd.hpp>
#include <boost/test/utils/runtime/errors.hpp>

// Boost.Test
#include <boost/test/utils/class_properties.hpp>
#include <boost/test/utils/rtti.hpp>
#include <boost/test/utils/basic_cstring/compare.hpp>
#include <boost/test/detail/throw_exception.hpp>

// STL
#include <cassert>

#include <boost/test/detail/suppress_warnings.hpp>

namespace boost {
namespace runtime {

// ************************************************************************** //
// **************              runtime::argument               ************** //
// ************************************************************************** //

class argument {
public:
    // Constructor
    argument( rtti::id_t value_type )
    : p_value_type( value_type )
    {}

    // Destructor
    virtual     ~argument()  {}

    // Public properties
    rtti::id_t const    p_value_type;
};

// ************************************************************************** //
// **************             runtime::typed_argument          ************** //
// ************************************************************************** //

template<typename T>
class typed_argument : public argument {
public:
    // Constructor
    explicit typed_argument( T const& v )
    : argument( rtti::type_id<T>() )
    , p_value( v )
    {}

    unit_test::readwrite_property<T>    p_value;
};

// ************************************************************************** //
// **************           runtime::arguments_store          ************** //
// ************************************************************************** //

class arguments_store {
public:
    typedef std::map<cstring, argument_ptr> storage_type;

    /// Returns number of arguments in the store; mostly used for testing
    std::size_t size() const        { return m_arguments.size(); }

    /// Clears the store for reuse
    void        clear()             { m_arguments.clear(); }

    /// Returns true if there is an argument corresponding to the specified parameter name
    bool        has( cstring parameter_name ) const
    {
        return m_arguments.find( parameter_name ) != m_arguments.end();
    }

    /// Provides types access to argument value by parameter name
    template<typename T>
    T const&    get( cstring parameter_name ) const {
        return const_cast<arguments_store*>(this)->get<T>( parameter_name );
    }

    template<typename T>
    T&          get( cstring parameter_name ) {
        storage_type::const_iterator found = m_arguments.find( parameter_name );
        BOOST_TEST_I_ASSRT( found != m_arguments.end(),
                            access_to_missing_argument() 
                                << "There is no argument provided for parameter "
                                << parameter_name );

        argument_ptr arg = found->second;

        BOOST_TEST_I_ASSRT( arg->p_value_type == rtti::type_id<T>(),
                            arg_type_mismatch()
                                << "Access with invalid type for argument corresponding to parameter "
                                << parameter_name );

        return static_cast<typed_argument<T>&>( *arg ).p_value.value;
    }

    /// Set's the argument value for specified parameter name
    template<typename T>
    void        set( cstring parameter_name, T const& value )
    {
        m_arguments[parameter_name] = argument_ptr( new typed_argument<T>( value ) );
    }

private:
    // Data members
    storage_type            m_arguments;
};

} // namespace runtime
} // namespace boost

#include <boost/test/detail/enable_warnings.hpp>

#endif // BOOST_TEST_UTILS_RUNTIME_ARGUMENT_HPP