class_properties.hpp 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  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 : simple facility that mimmic notion of read-only read-write
  12. // properties in C++ classes. Original idea by Henrik Ravn.
  13. // ***************************************************************************
  14. #ifndef BOOST_TEST_UTILS_CLASS_PROPERTIES_HPP
  15. #define BOOST_TEST_UTILS_CLASS_PROPERTIES_HPP
  16. // Boost.Test
  17. #include <boost/test/detail/config.hpp>
  18. // Boost
  19. #if !BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(600))
  20. #include <boost/preprocessor/seq/for_each.hpp>
  21. #endif
  22. #include <boost/call_traits.hpp>
  23. #include <boost/type_traits/add_pointer.hpp>
  24. #include <boost/type_traits/add_const.hpp>
  25. #include <boost/utility/addressof.hpp>
  26. // STL
  27. #include <iosfwd>
  28. #include <boost/test/detail/suppress_warnings.hpp>
  29. //____________________________________________________________________________//
  30. namespace boost {
  31. namespace unit_test {
  32. // ************************************************************************** //
  33. // ************** class_property ************** //
  34. // ************************************************************************** //
  35. template<class PropertyType>
  36. class class_property {
  37. protected:
  38. typedef typename call_traits<PropertyType>::const_reference read_access_t;
  39. typedef typename call_traits<PropertyType>::param_type write_param_t;
  40. typedef typename add_pointer<typename add_const<PropertyType>::type>::type address_res_t;
  41. public:
  42. // Constructor
  43. class_property() : value( PropertyType() ) {}
  44. explicit class_property( write_param_t init_value )
  45. : value( init_value ) {}
  46. // Access methods
  47. operator read_access_t() const { return value; }
  48. read_access_t get() const { return value; }
  49. bool operator!() const { return !value; }
  50. address_res_t operator&() const { return &value; }
  51. // Data members
  52. #ifndef BOOST_TEST_NO_PROTECTED_USING
  53. protected:
  54. #endif
  55. PropertyType value;
  56. };
  57. //____________________________________________________________________________//
  58. #ifdef BOOST_CLASSIC_IOSTREAMS
  59. template<class PropertyType>
  60. inline std::ostream&
  61. operator<<( std::ostream& os, class_property<PropertyType> const& p )
  62. #else
  63. template<typename CharT1, typename Tr,class PropertyType>
  64. inline std::basic_ostream<CharT1,Tr>&
  65. operator<<( std::basic_ostream<CharT1,Tr>& os, class_property<PropertyType> const& p )
  66. #endif
  67. {
  68. return os << p.get();
  69. }
  70. //____________________________________________________________________________//
  71. #define DEFINE_PROPERTY_FREE_BINARY_OPERATOR( op ) \
  72. template<class PropertyType> \
  73. inline bool \
  74. operator op( PropertyType const& lhs, class_property<PropertyType> const& rhs ) \
  75. { \
  76. return lhs op rhs.get(); \
  77. } \
  78. template<class PropertyType> \
  79. inline bool \
  80. operator op( class_property<PropertyType> const& lhs, PropertyType const& rhs ) \
  81. { \
  82. return lhs.get() op rhs; \
  83. } \
  84. template<class PropertyType> \
  85. inline bool \
  86. operator op( class_property<PropertyType> const& lhs, \
  87. class_property<PropertyType> const& rhs ) \
  88. { \
  89. return lhs.get() op rhs.get(); \
  90. } \
  91. /**/
  92. DEFINE_PROPERTY_FREE_BINARY_OPERATOR( == )
  93. DEFINE_PROPERTY_FREE_BINARY_OPERATOR( != )
  94. #undef DEFINE_PROPERTY_FREE_BINARY_OPERATOR
  95. // ************************************************************************** //
  96. // ************** readonly_property ************** //
  97. // ************************************************************************** //
  98. template<class PropertyType>
  99. class readonly_property : public class_property<PropertyType> {
  100. typedef class_property<PropertyType> base_prop;
  101. typedef typename base_prop::address_res_t arrow_res_t;
  102. protected:
  103. typedef typename base_prop::write_param_t write_param_t;
  104. public:
  105. // Constructor
  106. readonly_property() {}
  107. explicit readonly_property( write_param_t init_value ) : base_prop( init_value ) {}
  108. // access methods
  109. arrow_res_t operator->() const { return boost::addressof( base_prop::value ); }
  110. };
  111. //____________________________________________________________________________//
  112. #if BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(600))
  113. #define BOOST_READONLY_PROPERTY( property_type, friends ) boost::unit_test::readwrite_property<property_type >
  114. #else
  115. #define BOOST_READONLY_PROPERTY_DECLARE_FRIEND(r, data, elem) friend class elem;
  116. #define BOOST_READONLY_PROPERTY( property_type, friends ) \
  117. class BOOST_JOIN( readonly_property, __LINE__ ) \
  118. : public boost::unit_test::readonly_property<property_type > { \
  119. typedef boost::unit_test::readonly_property<property_type > base_prop; \
  120. BOOST_PP_SEQ_FOR_EACH( BOOST_READONLY_PROPERTY_DECLARE_FRIEND, ' ', friends ) \
  121. typedef base_prop::write_param_t write_param_t; \
  122. public: \
  123. BOOST_JOIN( readonly_property, __LINE__ )() {} \
  124. explicit BOOST_JOIN( readonly_property, __LINE__ )( write_param_t init_v ) \
  125. : base_prop( init_v ) {} \
  126. } \
  127. /**/
  128. #endif
  129. // ************************************************************************** //
  130. // ************** readwrite_property ************** //
  131. // ************************************************************************** //
  132. template<class PropertyType>
  133. class readwrite_property : public class_property<PropertyType> {
  134. typedef class_property<PropertyType> base_prop;
  135. typedef typename add_pointer<PropertyType>::type arrow_res_t;
  136. typedef typename base_prop::address_res_t const_arrow_res_t;
  137. typedef typename base_prop::write_param_t write_param_t;
  138. public:
  139. readwrite_property() : base_prop() {}
  140. explicit readwrite_property( write_param_t init_value ) : base_prop( init_value ) {}
  141. // access methods
  142. void set( write_param_t v ) { base_prop::value = v; }
  143. arrow_res_t operator->() { return boost::addressof( base_prop::value ); }
  144. const_arrow_res_t operator->() const { return boost::addressof( base_prop::value ); }
  145. #ifndef BOOST_TEST_NO_PROTECTED_USING
  146. using base_prop::value;
  147. #endif
  148. };
  149. //____________________________________________________________________________//
  150. } // unit_test
  151. } // namespace boost
  152. #include <boost/test/detail/enable_warnings.hpp>
  153. #undef BOOST_TEST_NO_PROTECTED_USING
  154. #endif // BOOST_TEST_UTILS_CLASS_PROPERTIES_HPP