1 ////////////////////////////////////////////////////////////////////////////// 2 // 3 // (C) Copyright Ion Gaztanaga 2015-2016. 4 // Distributed under the Boost Software License, Version 1.0. 5 // (See accompanying file LICENSE_1_0.txt or copy at 6 // http://www.boost.org/LICENSE_1_0.txt) 7 // 8 // See http://www.boost.org/libs/move for documentation. 9 // 10 ////////////////////////////////////////////////////////////////////////////// 11 12 #ifndef BOOST_MOVE_TEST_ORDER_TYPE_HPP 13 #define BOOST_MOVE_TEST_ORDER_TYPE_HPP 14 15 #include <boost/config.hpp> 16 #include <boost/move/core.hpp> 17 #include <boost/move/detail/iterator_traits.hpp> 18 #include <cstddef> 19 #include <cstdio> 20 21 struct order_perf_type 22 { 23 public: 24 std::size_t key; 25 std::size_t val; 26 order_perf_typeorder_perf_type27 order_perf_type() 28 { 29 ++num_elements; 30 } 31 order_perf_typeorder_perf_type32 order_perf_type(const order_perf_type& other) 33 : key(other.key), val(other.val) 34 { 35 ++num_elements; 36 ++num_copy; 37 } 38 operator =order_perf_type39 order_perf_type & operator=(const order_perf_type& other) 40 { 41 ++num_copy; 42 key = other.key; 43 val = other.val; 44 return *this; 45 } 46 ~order_perf_typeorder_perf_type47 ~order_perf_type () 48 { 49 --num_elements; 50 } 51 reset_statsorder_perf_type52 static void reset_stats() 53 { 54 num_compare=0; 55 num_copy=0; 56 } 57 operator <(const order_perf_type & left,const order_perf_type & right)58 friend bool operator< (const order_perf_type& left, const order_perf_type& right) 59 { ++num_compare; return left.key < right.key; } 60 61 static boost::ulong_long_type num_compare; 62 static boost::ulong_long_type num_copy; 63 static boost::ulong_long_type num_elements; 64 }; 65 66 boost::ulong_long_type order_perf_type::num_compare = 0; 67 boost::ulong_long_type order_perf_type::num_copy = 0; 68 boost::ulong_long_type order_perf_type::num_elements = 0; 69 70 71 struct order_move_type 72 { 73 BOOST_MOVABLE_BUT_NOT_COPYABLE(order_move_type) 74 75 public: 76 std::size_t key; 77 std::size_t val; 78 79 static const std::size_t moved_constr_mark = std::size_t(-1); 80 static const std::size_t moved_assign_mark = std::size_t(-2); 81 order_move_typeorder_move_type82 order_move_type() 83 : key(0u), val(0u) 84 {} 85 order_move_typeorder_move_type86 order_move_type(BOOST_RV_REF(order_move_type) other) 87 : key(other.key), val(other.val) 88 { 89 other.key = other.val = std::size_t(-1); 90 } 91 operator =order_move_type92 order_move_type & operator=(BOOST_RV_REF(order_move_type) other) 93 { 94 key = other.key; 95 val = other.val; 96 other.key = other.val = std::size_t(-2); 97 return *this; 98 } 99 operator <(const order_move_type & left,const order_move_type & right)100 friend bool operator< (const order_move_type& left, const order_move_type& right) 101 { return left.key < right.key; } 102 ~order_move_typeorder_move_type103 ~order_move_type () 104 { 105 key = val = std::size_t(-3); 106 } 107 }; 108 109 struct order_type_less 110 { 111 template<class T, class U> operator ()order_type_less112 bool operator()(const T &a, U const &b) const 113 { return a < b; } 114 }; 115 116 template<class T> is_order_type_ordered(T * elements,std::size_t element_count,bool stable=true)117 inline bool is_order_type_ordered(T *elements, std::size_t element_count, bool stable = true) 118 { 119 for(std::size_t i = 1; i < element_count; ++i){ 120 if(order_type_less()(elements[i], elements[i-1])){ 121 std::printf("\n Ord KO !!!!"); 122 return false; 123 } 124 if( stable && !(order_type_less()(elements[i-1], elements[i])) && (elements[i-1].val > elements[i].val) ){ 125 std::printf("\n Stb KO !!!! "); 126 return false; 127 } 128 } 129 return true; 130 } 131 132 namespace boost { 133 namespace movelib { 134 namespace detail_adaptive { 135 136 137 138 }}} 139 140 template<class T> is_key(T * elements,std::size_t element_count)141 inline bool is_key(T *elements, std::size_t element_count) 142 { 143 for(std::size_t i = 1; i < element_count; ++i){ 144 if(elements[i].key >= element_count){ 145 std::printf("\n Key.key KO !!!!"); 146 return false; 147 } 148 if(elements[i].val != std::size_t(-1)){ 149 std::printf("\n Key.val KO !!!!"); 150 return false; 151 } 152 } 153 return true; 154 } 155 156 template<class T> is_buffer(T * elements,std::size_t element_count)157 inline bool is_buffer(T *elements, std::size_t element_count) 158 { 159 for(std::size_t i = 1; i < element_count; ++i){ 160 if(elements[i].key != std::size_t(-1)){ 161 std::printf("\n Buf.key KO !!!!"); 162 return false; 163 } 164 if(elements[i].val >= element_count){ 165 std::printf("\n Buf.val KO !!!!"); 166 return false; 167 } 168 } 169 return true; 170 } 171 172 173 //size_type iterator 174 template <class T, class D> 175 class randit 176 { 177 public: 178 typedef std::random_access_iterator_tag iterator_category; 179 typedef T value_type; 180 typedef D difference_type; 181 typedef T* pointer; 182 typedef T& reference; 183 184 private: 185 T* m_ptr; 186 187 public: randit(T * ptr)188 explicit randit(T* ptr) 189 : m_ptr(ptr) 190 {} 191 192 public: 193 194 //Constructors randit()195 randit() 196 : m_ptr() //Value initialization to achieve "null iterators" (N3644) 197 {} 198 randit(const randit & other)199 randit(const randit& other) 200 : m_ptr(other.m_ptr) 201 {} 202 operator =(const randit & other)203 randit & operator=(const randit& other) 204 { m_ptr = other.m_ptr; return *this; } 205 206 //T* like operators operator *() const207 reference operator*() const 208 { return *m_ptr; } 209 operator ->() const210 pointer operator->() const 211 { return m_ptr; } 212 operator [](difference_type off) const213 reference operator[](difference_type off) const 214 { return m_ptr[off]; } 215 216 //Increment / Decrement operator ++()217 randit& operator++() 218 { ++m_ptr; return *this; } 219 operator ++(int)220 randit operator++(int) 221 { return randit(m_ptr++); } 222 operator --()223 randit& operator--() 224 { --m_ptr; return *this; } 225 operator --(int)226 randit operator--(int) 227 { return randit(m_ptr--); } 228 229 //Arithmetic operator +=(difference_type off)230 randit& operator+=(difference_type off) 231 { m_ptr += off; return *this; } 232 operator -=(difference_type off)233 randit& operator-=(difference_type off) 234 { m_ptr -= off; return *this; } 235 operator +(const randit & x,difference_type off)236 friend randit operator+(const randit &x, difference_type off) 237 { return randit(x.m_ptr+off); } 238 operator +(difference_type off,randit right)239 friend randit operator+(difference_type off, randit right) 240 { right.m_ptr += off; return right; } 241 operator -(randit left,difference_type off)242 friend randit operator-(randit left, difference_type off) 243 { left.m_ptr -= off; return left; } 244 operator -(const randit & left,const randit & right)245 friend difference_type operator-(const randit &left, const randit& right) 246 { return difference_type(left.m_ptr - right.m_ptr); } 247 248 //Comparison operators operator ==(const randit & l,const randit & r)249 friend bool operator== (const randit& l, const randit& r) 250 { return l.m_ptr == r.m_ptr; } 251 operator !=(const randit & l,const randit & r)252 friend bool operator!= (const randit& l, const randit& r) 253 { return l.m_ptr != r.m_ptr; } 254 operator <(const randit & l,const randit & r)255 friend bool operator< (const randit& l, const randit& r) 256 { return l.m_ptr < r.m_ptr; } 257 operator <=(const randit & l,const randit & r)258 friend bool operator<= (const randit& l, const randit& r) 259 { return l.m_ptr <= r.m_ptr; } 260 operator >(const randit & l,const randit & r)261 friend bool operator> (const randit& l, const randit& r) 262 { return l.m_ptr > r.m_ptr; } 263 operator >=(const randit & l,const randit & r)264 friend bool operator>= (const randit& l, const randit& r) 265 { return l.m_ptr >= r.m_ptr; } 266 }; 267 268 struct less_int 269 { operator ()less_int270 bool operator()(int l, int r) 271 { return l < r; } 272 }; 273 274 275 #endif //BOOST_MOVE_TEST_ORDER_TYPE_HPP 276