1 // (C) Copyright Raffi Enficiaud 2016. 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 9 /// Tests the variadic sample element support and the respect of move semantics 10 /// for the datasets definitions 11 // *************************************************************************** 12 13 // Boost.Test 14 #define BOOST_TEST_MODULE test movable return type on datasets test 15 #include <boost/test/unit_test.hpp> 16 #include <boost/test/data/test_case.hpp> 17 18 #include <boost/test/data/monomorphic/singleton.hpp> 19 #include <boost/test/data/monomorphic/collection.hpp> 20 #include <boost/test/data/for_each_sample.hpp> 21 22 23 namespace utf=boost::unit_test; 24 namespace bdata=utf::data; 25 26 #include <vector> 27 #include <list> 28 29 30 class non_copyable_type 31 { 32 public: 33 static int nb_rvalue_construct; 34 static int nb_rvalue_assignment; 35 static int nb_destructs; 36 37 non_copyable_type(const non_copyable_type&) = delete; 38 non_copyable_type& operator=(const non_copyable_type&) = delete; 39 ~non_copyable_type()40 ~non_copyable_type() { 41 nb_destructs++; 42 } 43 non_copyable_type(non_copyable_type && rhs)44 non_copyable_type(non_copyable_type&& rhs) 45 { 46 value_ = rhs.value_; 47 rhs.value_ = -1; 48 nb_rvalue_construct++; 49 } operator =(non_copyable_type && rhs)50 non_copyable_type& operator=(non_copyable_type&& rhs) { 51 value_ = rhs.value_; 52 rhs.value_ = -1; 53 nb_rvalue_assignment++; 54 return *this; 55 } 56 non_copyable_type(const int value)57 explicit non_copyable_type(const int value) 58 { 59 value_ = value; 60 } 61 operator <<(std::ostream & ost,const non_copyable_type & rhs)62 friend std::ostream& operator<<(std::ostream& ost, const non_copyable_type& rhs) 63 { 64 ost << "non_copyable_type: " << rhs.value_ << std::endl; 65 return ost; 66 } 67 get() const68 int get() const { 69 return value_; 70 } 71 72 private: 73 int value_; 74 }; 75 76 int non_copyable_type::nb_rvalue_construct = 0; 77 int non_copyable_type::nb_rvalue_assignment = 0; 78 int non_copyable_type::nb_destructs = 0; 79 80 // Dataset generating a Fibonacci sequence 81 // The return type is either a regular int or a non-movable type 82 template <class return_t = int> 83 class fibonacci_dataset { 84 public: 85 enum { arity = 1 }; 86 87 struct iterator { 88 iteratorfibonacci_dataset::iterator89 iterator() : a(1), b(1) {} 90 operator *fibonacci_dataset::iterator91 return_t operator*() const { return return_t(b); } operator ++fibonacci_dataset::iterator92 void operator++() 93 { 94 a = a + b; 95 std::swap(a, b); 96 } 97 private: 98 int a; 99 int b; // b is the output 100 }; 101 fibonacci_dataset()102 fibonacci_dataset() {} 103 104 // size is infinite size() const105 bdata::size_t size() const { return bdata::BOOST_TEST_DS_INFINITE_SIZE; } 106 107 // iterator begin() const108 iterator begin() const { return iterator(); } 109 }; 110 111 namespace boost { namespace unit_test { namespace data { namespace monomorphic { 112 // registering fibonacci_dataset as a proper dataset 113 template <> 114 struct is_dataset< fibonacci_dataset<int> > : boost::mpl::true_ {}; 115 116 template <> 117 struct is_dataset< fibonacci_dataset<non_copyable_type> > : boost::mpl::true_ {}; 118 }}}} 119 120 // Creating a test-driven dataset 121 BOOST_DATA_TEST_CASE( 122 test1, 123 fibonacci_dataset<int>() ^ bdata::make( { 1, 2, 3, 5, 8, 13, 21, 34, 55 } ), 124 fib_sample, exp) 125 { 126 BOOST_TEST(fib_sample == exp); 127 } 128 129 BOOST_DATA_TEST_CASE( 130 test2, 131 fibonacci_dataset<non_copyable_type>() ^ bdata::make( { 1, 2, 3, 5, 8, 13, 21, 34, 55 } ), 132 fib_sample, exp) 133 { 134 BOOST_TEST(fib_sample.get() == exp); 135 } 136 137 //____________________________________________________________________________// 138 139 // EOF 140