argument_factory.hpp 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  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. // See http://www.boost.org/libs/test for the library home page.
  6. //
  7. // File : $RCSfile$
  8. //
  9. // Version : $Revision$
  10. //
  11. // Description : argument factories for different kinds of parameters
  12. // ***************************************************************************
  13. #ifndef BOOST_TEST_UTILS_RUNTIME_ARGUMENT_FACTORY_HPP
  14. #define BOOST_TEST_UTILS_RUNTIME_ARGUMENT_FACTORY_HPP
  15. // Boost.Test Runtime parameters
  16. #include <boost/test/utils/runtime/errors.hpp>
  17. #include <boost/test/utils/runtime/argument.hpp>
  18. #include <boost/test/utils/runtime/modifier.hpp>
  19. // Boost.Test
  20. #include <boost/test/utils/basic_cstring/io.hpp>
  21. #include <boost/test/utils/basic_cstring/compare.hpp>
  22. #include <boost/test/utils/string_cast.hpp>
  23. // Boost
  24. #include <boost/function/function2.hpp>
  25. // STL
  26. #include <vector>
  27. #include <boost/test/detail/suppress_warnings.hpp>
  28. namespace boost {
  29. namespace runtime {
  30. // ************************************************************************** //
  31. // ************** runtime::value_interpreter ************** //
  32. // ************************************************************************** //
  33. template<typename ValueType, bool is_enum>
  34. struct value_interpreter;
  35. //____________________________________________________________________________//
  36. template<typename ValueType>
  37. struct value_interpreter<ValueType, false> {
  38. template<typename Modifiers>
  39. explicit value_interpreter( Modifiers const& ) {}
  40. ValueType interpret( cstring param_name, cstring source ) const
  41. {
  42. ValueType res;
  43. if( !unit_test::utils::string_as<ValueType>( source, res ) )
  44. BOOST_TEST_I_THROW( format_error( param_name ) << source <<
  45. " can't be interpreted as value of parameter " << param_name << "." );
  46. return res;
  47. }
  48. };
  49. //____________________________________________________________________________//
  50. template<>
  51. struct value_interpreter<std::string, false> {
  52. template<typename Modifiers>
  53. explicit value_interpreter( Modifiers const& ) {}
  54. std::string interpret( cstring, cstring source ) const
  55. {
  56. return std::string( source.begin(), source.size() );
  57. }
  58. };
  59. //____________________________________________________________________________//
  60. template<>
  61. struct value_interpreter<cstring, false> {
  62. template<typename Modifiers>
  63. explicit value_interpreter( Modifiers const& ) {}
  64. cstring interpret( cstring, cstring source ) const
  65. {
  66. return source;
  67. }
  68. };
  69. //____________________________________________________________________________//
  70. template<>
  71. struct value_interpreter<bool, false> {
  72. template<typename Modifiers>
  73. explicit value_interpreter( Modifiers const& ) {}
  74. bool interpret( cstring param_name, cstring source ) const
  75. {
  76. static cstring const s_YES( "YES" );
  77. static cstring const s_Y( "Y" );
  78. static cstring const s_NO( "NO" );
  79. static cstring const s_N( "N" );
  80. static cstring const s_TRUE( "TRUE" );
  81. static cstring const s_FALSE( "FALSE" );
  82. static cstring const s_one( "1" );
  83. static cstring const s_zero( "0" );
  84. source.trim();
  85. if( source.is_empty() ||
  86. case_ins_eq( source, s_YES ) ||
  87. case_ins_eq( source, s_Y ) ||
  88. case_ins_eq( source, s_one ) ||
  89. case_ins_eq( source, s_TRUE ) )
  90. return true;
  91. if( case_ins_eq( source, s_NO ) ||
  92. case_ins_eq( source, s_N ) ||
  93. case_ins_eq( source, s_zero ) ||
  94. case_ins_eq( source, s_FALSE ) )
  95. return false;
  96. BOOST_TEST_I_THROW( format_error( param_name ) << source << " can't be interpreted as bool value." );
  97. }
  98. };
  99. //____________________________________________________________________________//
  100. template<typename EnumType>
  101. struct value_interpreter<EnumType, true> {
  102. template<typename Modifiers>
  103. explicit value_interpreter( Modifiers const& m )
  104. #if defined(BOOST_TEST_CLA_NEW_API)
  105. : m_name_to_value( m[enum_values<EnumType>::value] )
  106. {
  107. }
  108. #else
  109. {
  110. std::vector<std::pair<cstring,EnumType> > const& values = m[enum_values<EnumType>::value];
  111. m_name_to_value.insert( values.begin(), values.end() );
  112. }
  113. #endif
  114. EnumType interpret( cstring param_name, cstring source ) const
  115. {
  116. typename std::map<cstring,EnumType>::const_iterator found = m_name_to_value.find( source );
  117. BOOST_TEST_I_ASSRT( found != m_name_to_value.end(),
  118. format_error( param_name ) << source <<
  119. " is not a valid enumeration value name for parameter " << param_name << "." );
  120. return found->second;
  121. }
  122. private:
  123. // Data members
  124. std::map<cstring,EnumType> m_name_to_value;
  125. };
  126. //____________________________________________________________________________//
  127. // ************************************************************************** //
  128. // ************** runtime::argument_factory ************** //
  129. // ************************************************************************** //
  130. template<typename ValueType, bool is_enum, bool repeatable>
  131. class argument_factory;
  132. //____________________________________________________________________________//
  133. template<typename ValueType, bool is_enum>
  134. class argument_factory<ValueType, is_enum, false> {
  135. public:
  136. template<typename Modifiers>
  137. explicit argument_factory( Modifiers const& m )
  138. : m_interpreter( m )
  139. , m_optional_value( nfp::opt_get( m, optional_value, ValueType() ) )
  140. , m_default_value( nfp::opt_get( m, default_value, ValueType() ) )
  141. {
  142. }
  143. void produce_argument( cstring source, cstring param_name, arguments_store& store ) const
  144. {
  145. store.set( param_name, source.empty() ? m_optional_value : m_interpreter.interpret( param_name, source ) );
  146. }
  147. void produce_default( cstring param_name, arguments_store& store ) const
  148. {
  149. store.set( param_name, m_default_value );
  150. }
  151. private:
  152. // Data members
  153. typedef value_interpreter<ValueType, is_enum> interp_t;
  154. interp_t m_interpreter;
  155. ValueType m_optional_value;
  156. ValueType m_default_value;
  157. };
  158. //____________________________________________________________________________//
  159. template<typename ValueType, bool is_enum>
  160. class argument_factory<ValueType, is_enum, true> {
  161. public:
  162. template<typename Modifiers>
  163. explicit argument_factory( Modifiers const& m )
  164. : m_interpreter( m )
  165. {
  166. }
  167. void produce_argument( cstring source, cstring param_name, arguments_store& store ) const
  168. {
  169. ValueType value = m_interpreter.interpret( param_name, source );
  170. if( store.has( param_name ) ) {
  171. std::vector<ValueType>& values = store.get<std::vector<ValueType> >( param_name );
  172. values.push_back( value );
  173. }
  174. else {
  175. std::vector<ValueType> values( 1, value );
  176. store.set( param_name, values );
  177. }
  178. }
  179. void produce_default( cstring param_name, arguments_store& store ) const
  180. {
  181. store.set( param_name, std::vector<ValueType>() );
  182. }
  183. private:
  184. // Data members
  185. value_interpreter<ValueType, is_enum> m_interpreter;
  186. };
  187. //____________________________________________________________________________//
  188. } // namespace runtime
  189. } // namespace boost
  190. #include <boost/test/detail/enable_warnings.hpp>
  191. #endif // BOOST_TEST_UTILS_RUNTIME_ARGUMENT_FACTORY_HPP