1 //  (C) Copyright Gennadiy Rozental 2005-2008.
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: 54633 $
11 //
12 //  Description : defines model of program environment variable
13 // ***************************************************************************
14 
15 #ifndef BOOST_RT_ENV_VARIABLE_HPP_062604GER
16 #define BOOST_RT_ENV_VARIABLE_HPP_062604GER
17 
18 #ifdef UNDER_CE
19 #error Windows CE does not support environment variables.
20 #endif
21 
22 // Boost.Runtime.Parameter
23 #include <boost/test/utils/runtime/config.hpp>
24 #include <boost/test/utils/runtime/fwd.hpp>
25 #include <boost/test/utils/runtime/parameter.hpp>
26 #include <boost/test/utils/runtime/argument.hpp>
27 
28 #include <boost/test/utils/runtime/env/fwd.hpp>
29 
30 // Boost
31 #include <boost/optional.hpp>
32 
33 namespace boost {
34 
35 namespace BOOST_RT_PARAM_NAMESPACE {
36 
37 namespace environment {
38 
39 // ************************************************************************** //
40 // **************      runtime::environment::variable_data     ************** //
41 // ************************************************************************** //
42 
43 namespace rt_env_detail {
44 
45 struct variable_data : public runtime::parameter {
46     cstring         m_var_name;
47     dstring         m_global_id;
48     argument_ptr    m_value;
49 };
50 
51 } // namespace rt_env_detail
52 
53 // ************************************************************************** //
54 // **************     runtime::environment::variable_base      ************** //
55 // ************************************************************************** //
56 
57 class variable_base {
58 public:
variable_base(rt_env_detail::variable_data & data)59     explicit    variable_base( rt_env_detail::variable_data& data ) : m_data( &data ) {}
60 
61     // arguments access
62     template<typename T>
value() const63     T const&    value() const
64     {
65         return arg_value<T>( *m_data->m_value );
66     }
67 
68     template<typename T>
value(boost::optional<T> & res) const69     void        value( boost::optional<T>& res ) const
70     {
71         if( has_value() )
72             res = arg_value<T>( *m_data->m_value );
73         else
74             res.reset();
75     }
76 
has_value() const77     bool        has_value() const   { return m_data->m_value; }
name() const78     cstring     name() const        { return m_data->m_var_name; }
79 
80 protected:
81     // Data members
82     rt_env_detail::variable_data*  m_data;
83 } ;
84 
85 // ************************************************************************** //
86 // **************        runtime::environment::variable        ************** //
87 // ************************************************************************** //
88 
89 template<typename T = cstring>
90 class variable : public variable_base {
91 public:
92     // Constructors
93     explicit    variable( cstring var_name );
94 
95     template<typename Modifiers>
96     explicit    variable( cstring var_name, Modifiers const& m );
97 
variable(rt_env_detail::variable_data & data)98     explicit    variable( rt_env_detail::variable_data& data )
99     : variable_base( data )                                 {}
100 
101     // other variable assignment
operator =(variable const & v)102     void        operator=( variable const& v )              { m_data = v.m_data; }
103 
104     // access methods
value() const105     T const&    value() const                               { return variable_base::value<T>(); }
106 
107 #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3206)) || \
108     BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x0593))
109     template<typename T>
value(boost::optional<T> & res) const110     void        value( boost::optional<T>& res ) const      { variable_base::value( res ); }
111 #else
112     using       variable_base::value;
113 #endif
114 
115     // Value assignment
116     template<typename V>
operator =(V const & v)117     void        operator=( V const& v )
118     {
119         if( !has_value() )
120             m_data->m_value.reset( new typed_argument<T>( *m_data ) );
121 
122         arg_value<T>( *m_data->m_value ) = v;
123 
124         rt_env_detail::sys_write_var( m_data->m_var_name, format_stream().ref() << value() );
125     }
126 }; // class variable
127 
128 //____________________________________________________________________________//
129 
130 template<typename CharT, typename Tr,typename T>
131 inline std::basic_ostream<CharT,Tr>&
operator <<(std::basic_ostream<CharT,Tr> & os,variable<T> const & v)132 operator<<( std::basic_ostream<CharT,Tr>& os, variable<T> const& v )
133 {
134     os << v.name() << '=';
135 
136     if( v.has_value() )
137         os << v.value();
138 
139     return os;
140 }
141 
142 //____________________________________________________________________________//
143 
144 template<typename T, typename V>
145 inline bool
operator ==(variable<T> ev,V const & v)146 operator==( variable<T> ev, V const& v )
147 {
148     return ev.has_value() && ev.value() == v;
149 }
150 
151 //____________________________________________________________________________//
152 
153 template<typename T, typename V>
154 inline bool
operator ==(V const & v,variable<T> ev)155 operator==( V const& v, variable<T> ev )
156 {
157     return ev.has_value() && ev.value() == v;
158 }
159 
160 //____________________________________________________________________________//
161 
162 template<typename T, typename V>
163 inline bool
operator !=(variable<T> ev,V const & v)164 operator!=( variable<T> ev, V const& v )
165 {
166     return !ev.has_value() || ev.value() != v;
167 }
168 
169 //____________________________________________________________________________//
170 
171 template<typename T, typename V>
172 inline bool
operator !=(V const & v,variable<T> ev)173 operator!=( V const& v, variable<T> ev )
174 {
175     return !ev.has_value() || ev.value() != v;
176 }
177 
178 //____________________________________________________________________________//
179 
180 } // namespace environment
181 
182 } // namespace BOOST_RT_PARAM_NAMESPACE
183 
184 } // namespace boost
185 
186 // ************************************************************************** //
187 // ************************************************************************** //
188 // Implementation
189 
190 #include <boost/test/utils/runtime/env/environment.hpp>
191 
192 // ************************************************************************** //
193 // **************        runtime::environment::variable        ************** //
194 // ************************************************************************** //
195 
196 namespace boost {
197 
198 namespace BOOST_RT_PARAM_NAMESPACE {
199 
200 namespace environment {
201 
202 template<typename T>
variable(cstring var_name)203 variable<T>::variable( cstring var_name )
204 : variable_base( environment::var<T>( var_name ) )
205 {}
206 
207 //____________________________________________________________________________//
208 
209 template<typename T>
210 template<typename Modifiers>
variable(cstring var_name,Modifiers const & m)211 variable<T>::variable( cstring var_name, Modifiers const& m )
212 : variable_base( environment::var<T>( var_name, m ) )
213 {}
214 
215 //____________________________________________________________________________//
216 
217 } // namespace environment
218 
219 } // namespace BOOST_RT_PARAM_NAMESPACE
220 
221 } // namespace boost
222 
223 #endif // BOOST_RT_ENV_VARIABLE_HPP_062604GER
224