chained.cpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. // Boost.Range library
  2. //
  3. // Copyright Neil Groves 2014. Use, modification and
  4. // distribution is subject to the Boost Software License, Version
  5. // 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt)
  7. //
  8. //
  9. // For more information, see http://www.boost.org/libs/range/
  10. //
  11. // Credits:
  12. // Jurgen Hunold provided a test case that demonstrated that the range adaptors
  13. // were producing iterators that were not default constructible. This became
  14. // symptomatic after enabling concept checking assertions. This test is a
  15. // lightly modified version of his supplied code to ensure that his use case
  16. // never breaks again. (hopefully!)
  17. //
  18. #include <boost/range/adaptor/transformed.hpp>
  19. #include <boost/range/adaptor/filtered.hpp>
  20. #include <boost/range/algorithm/copy.hpp>
  21. #include <boost/bind.hpp>
  22. #include <boost/test/test_tools.hpp>
  23. #include <boost/test/unit_test.hpp>
  24. #include <vector>
  25. #include <set>
  26. namespace boost_range_test
  27. {
  28. namespace
  29. {
  30. class foo
  31. {
  32. public:
  33. static foo from_string(const std::string& source)
  34. {
  35. foo f;
  36. f.m_valid = true;
  37. f.m_value = 0u;
  38. for (std::string::const_iterator it = source.begin();
  39. it != source.end(); ++it)
  40. {
  41. f.m_value += *it;
  42. if ((*it < 'a') || (*it > 'z'))
  43. f.m_valid = false;
  44. }
  45. return f;
  46. }
  47. bool is_valid() const
  48. {
  49. return m_valid;
  50. }
  51. bool operator<(const foo& other) const
  52. {
  53. return m_value < other.m_value;
  54. }
  55. bool operator==(const foo& other) const
  56. {
  57. return m_value == other.m_value && m_valid == other.m_valid;
  58. }
  59. bool operator!=(const foo& other) const
  60. {
  61. return !operator==(other);
  62. }
  63. friend inline std::ostream& operator<<(std::ostream& out, const foo& obj)
  64. {
  65. out << "{value=" << obj.m_value
  66. << ", valid=" << std::boolalpha << obj.m_valid << "}\n";
  67. return out;
  68. }
  69. private:
  70. boost::uint64_t m_value;
  71. bool m_valid;
  72. };
  73. void chained_adaptors_test()
  74. {
  75. std::vector<std::string> sep;
  76. sep.push_back("AB");
  77. sep.push_back("ab");
  78. sep.push_back("aghj");
  79. std::set<foo> foos;
  80. boost::copy(sep
  81. | boost::adaptors::transformed(boost::bind(&foo::from_string, _1))
  82. | boost::adaptors::filtered(boost::bind(&foo::is_valid, _1)),
  83. std::inserter(foos, foos.end()));
  84. std::vector<foo> reference;
  85. reference.push_back(foo::from_string("ab"));
  86. reference.push_back(foo::from_string("aghj"));
  87. BOOST_CHECK_EQUAL_COLLECTIONS(
  88. reference.begin(), reference.end(),
  89. foos.begin(), foos.end());
  90. }
  91. } // anonymous namespace
  92. } // namespace boost_range_test
  93. boost::unit_test::test_suite*
  94. init_unit_test_suite(int argc, char* argv[])
  95. {
  96. boost::unit_test::test_suite* test
  97. = BOOST_TEST_SUITE( "RangeTestSuite.adaptor.chained adaptors" );
  98. test->add(BOOST_TEST_CASE( boost_range_test::chained_adaptors_test));
  99. return test;
  100. }