Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base fork: marshray/qak
base: 92cf56a294
...
head fork: marshray/qak
compare: 63f14561d1
Checking mergeability… Don't worry, you can still create the pull request.
  • 2 commits
  • 8 files changed
  • 0 commit comments
  • 1 contributor
View
1  src/include/qak/config.hxx
@@ -71,6 +71,7 @@
// We have inline assembler like gcc's format.
# define QAK_INLINEASM_GCC 1
+ // We have exact-width integral types of 128 bits
# define QAK_INT128_TYPE __int128
# define QAK_UINT128_TYPE unsigned __int128
View
327 src/include/qak/permutation.hxx
@@ -0,0 +1,327 @@
+// vim: set ts=4 sw=4 tw=120:
+//=====================================================================================================================|
+//
+// Copyright (c) 2012, Marsh Ray
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+// OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+//
+//=====================================================================================================================|
+//
+//#include "qak/permutation.hxx"
+
+#ifndef qak_permutation_hxx_INCLUDED_
+#define qak_permutation_hxx_INCLUDED_
+
+#include "qak/vector.hxx"
+
+#include <cstdint>
+#include <type_traits> // is_integral
+
+namespace qak { //=====================================================================================================|
+
+namespace permutation_imp {
+
+ template <int N> struct size_type_of;
+ template <> struct size_type_of<1> { typedef std::uint8_t type; };
+ template <> struct size_type_of<2> { typedef std::uint16_t type; };
+ template <> struct size_type_of<4> { typedef std::uint32_t type; };
+ template <> struct size_type_of<8> { typedef std::uint64_t type; };
+
+ template <int N> struct index_permutation_imp
+ {
+ typedef typename permutation_imp::size_type_of<N>::type uint_type;
+
+ typedef qak::vector<uint_type> vector_type;
+ vector_type f_; // forward mapping
+ vector_type r_; // reverse mapping
+
+ index_permutation_imp() : f_(), r_() { }
+
+ index_permutation_imp(index_permutation_imp const & that) :
+ f_(that.f_), r_(that.r_)
+ { }
+
+ index_permutation_imp(index_permutation_imp && src) :
+ f_(), r_()
+ {
+ this->f_.swap(src.f_);
+ this->r_.swap(src.r_);
+ }
+
+ void copy_assign_from(index_permutation_imp const & that)
+ {
+ this->f_ = that.f_;
+ this->r_ = that.r_;
+ }
+
+ void move_assign_from(index_permutation_imp && src)
+ {
+ this->f_.clear();
+ this->r_.clear();
+ this->swap(src);
+ }
+
+ void swap(index_permutation_imp & that)
+ {
+ this->f_.swap(that.f_);
+ this->r_.swap(that.r_);
+ }
+
+ bool empty() const;
+ uint_type size() const;
+
+ uint_type f_at(uint_type ix) const;
+ uint_type r_at(uint_type ix) const;
+
+ void set_identity();
+ void reset(uint_type n);
+ void invert();
+ void extend(uint_type n);
+ void swap_two(uint_type ix_a, uint_type ix_b);
+ void rotate(uint_type ix_b, uint_type ix_m, uint_type ix_e);
+ void square();
+ void mult_by(index_permutation_imp const & that);
+ };
+
+ extern template struct index_permutation_imp<1>;
+ extern template struct index_permutation_imp<2>;
+ extern template struct index_permutation_imp<4>;
+ extern template struct index_permutation_imp<8>;
+
+} // namespace permutation_imp
+
+ //=================================================================================================================|
+
+ //-----------------------------------------------------------------------------------------------------------------|
+ //
+ // A permutation mapping of 0-based indices, i.e., a contiguous sequence of integers 0 - N.
+ //
+ template <
+ class size_type_T = std::size_t
+ >
+ struct index_permutation
+ {
+ static_assert(std::is_integral<size_type_T>::value, "size_type_T should be an integral type");
+
+ typedef size_type_T value_type;
+ typedef size_type_T size_type;
+
+ private:
+
+ typedef permutation_imp::index_permutation_imp<sizeof(size_type_T)> imp_t;
+ imp_t imp_;
+
+ typedef typename imp_t::uint_type uint_type;
+
+ uint_type to_imp(size_type n) const
+ {
+ assert(0 <= n && sizeof(size_type) <= sizeof(uint_type));
+ return static_cast<uint_type>(n);
+ }
+
+ size_type from_imp(uint_type n) const
+ {
+ assert(0 <= n && n <= to_imp(std::numeric_limits<size_type>::max()));
+ return static_cast<size_type>(n);
+ }
+
+ public:
+
+ //----- Struction.
+
+ // Default construction produces an empty set.
+ //
+ index_permutation() { }
+
+ // Copy construction.
+ //
+ index_permutation(index_permutation const & that) : imp_(that.imp_) { }
+
+ // Move construction.
+ //
+ index_permutation(index_permutation && src) : imp_(std::move(src.imp_)) { }
+
+ // Construction from a size_type produces the identity permutation over the specified count of elements.
+ //
+ explicit
+ index_permutation(size_type n) : imp_() { imp_.reset(n); }
+
+ //----- Assignment.
+
+ // Copy assign from same.
+ index_permutation & operator = (index_permutation const & that)
+ {
+ if (this != &that)
+ imp_.copy_assign_from(that.imp_);
+ return *this;
+ }
+
+ // Move assign from same.
+ index_permutation & operator = (index_permutation && that)
+ {
+ assert(this != &that);
+ this->imp_.move_assign_from(std::move(that.imp_));
+ return *this;
+ }
+
+ //----- Info.
+
+ bool empty() const { return imp_.empty(); }
+
+ size_type size() const { return from_imp(imp_.size()); }
+
+ //----- Lookup.
+
+ size_type f_at(size_type ix) const { assert(0 <= ix); return from_imp(imp_.f_at(to_imp(ix))); }
+ size_type r_at(size_type ix) const { assert(0 <= ix); return from_imp(imp_.r_at(to_imp(ix))); }
+
+ // The usual array container operators reflect the forward mapping.
+ size_type operator [] (size_type ix) const { return f_at(ix); }
+ size_type at(size_type ix) const { return f_at(ix); }
+
+ //----- Mutation.
+
+ // Resets the permutation to the identity mapping of the current count of elements.
+ void set_identity() { imp_.set_identity(); }
+
+ // Resets the permutation to the identity mapping of the specified count of elements.
+ void reset(size_type n) { imp_.reset(n); }
+
+ // Modifies the permutation in-place to represent the inverse mapping.
+ // This amounts to just some pointer swaps in the current implementation.
+ void invert() { imp_.invert(); }
+
+ // Swaps two positions specified by forward indices.
+ void swap_two(size_type ix_a, size_type ix_b)
+ {
+ assert(0 <= ix_a);
+ assert(0 <= ix_b);
+ imp_.swap_two(to_imp(ix_a), to_imp(ix_b));
+ }
+
+ // Extends the mapping by the specified count of elements.
+ // The newly-added indices assume an identity mapping.
+ void extend(size_type n) { assert(0 <= n); imp_.extend(to_imp(n)); }
+
+ // Rotates the specified range of forward indexes so that the element mapped
+ // by ix_m becomes mapped by ix_b.
+ void rotate(size_type ix_b, size_type ix_m, size_type ix_e)
+ {
+ assert(0 <= ix_b);
+ assert( ix_b <= ix_m);
+ assert( ix_m <= ix_e);
+ assert( ix_e <= from_imp(imp_.size()));
+ imp_.rotate(to_imp(ix_b), to_imp(ix_m), to_imp(ix_e));
+ }
+
+ // Multiplication
+
+ // Permutes the object by itself.
+ void square() { this->imp_.square(); }
+
+ index_permutation & operator *= (index_permutation const & that)
+ {
+ assert(this->size() == that.size());
+
+ if (this == &that)
+ this->imp_.square();
+ else
+ this->imp_.mult_by(that.imp_);
+
+ return *this;
+ }
+
+ //----- No-throw swap.
+
+ void swap(index_permutation & that) { this->imp_.swap(that.imp_); }
+
+ //----- Non-mutating operations.
+
+#if 1
+ bool operator == (index_permutation const & that) const
+#elif 0
+ template <class size_type_U>
+ bool operator == (index_permutation<size_type_U> const & that) const
+#elif 0
+#endif
+ {
+ if (this == &that)
+ {
+ return true;
+ }
+#if 1
+#elif 0
+ if (sizeof(size_type_U) < sizeof(size_type))
+ {
+ // Perhaps this will cut down on the number of full template instantiations.
+ return that.operator == (*this);
+ }
+#elif 0
+#endif
+ else
+ {
+ //? TODO This is interesting. Would it make sense to logically extend the shorter permutation
+ // with the identity mapping in order to compare unequal permutations?
+ size_type sz = this->imp_.size();
+ if (sz != that.size())
+ return false;
+
+ //? TODO could we use memcmp here?
+ for (size_type ix = 0; ix < sz; ++ix)
+ if (this->imp_.f_[ix] != that.imp_.f_[ix])
+ return false;
+
+ return true;
+ }
+ }
+
+ template <class size_type_U>
+ bool operator != (index_permutation<size_type_U> const & that) const
+ {
+ return ! this->operator == (that);
+ }
+ };
+
+ //=================================================================================================================|
+
+ template <class size_type_T>
+ inline index_permutation<size_type_T> operator * (
+ index_permutation<size_type_T> const & a,
+ index_permutation<size_type_T> const & b )
+ {
+ index_permutation<size_type_T> c(a);
+
+ if (&a == &b)
+ c.square();
+ else
+ c *= b; //? OPT could possibly eliminate the copy initialization of c.
+
+ return c;
+ }
+
+ //-----------------------------------------------------------------------------------------------------------------|
+
+} // namespace qak ====================================================================================================|
+namespace std {
+
+ template <class size_type_T>
+ inline void swap(::qak::index_permutation<size_type_T> & a, ::qak::index_permutation<size_type_T> & b)
+ {
+ a.swap(b);
+ }
+
+ //? template <class size_type_T> struct hash;
+ //? template <class size_type_T> struct hash<::qak::index_permutation<size_type_T>>;
+
+} // namespace std ====================================================================================================|
+#endif // ndef qak_permutation_hxx_INCLUDED_
View
3  src/include/qak/test_macros.hxx
@@ -33,5 +33,8 @@
// Check that the two macro arguments compare equal with '=='.
#define QAK_verify_equal(a, b) if ((a) == (b)) { } else QAK_fail_test()
+// Check that the macro argument is zero.
+#define QAK_verify_zero(a) if ((a) == 0) { } else QAK_fail_test()
+
//=====================================================================================================================|
#endif // ndef qak_test_macros_hxx_INCLUDED_
View
43 src/include/qak/vector.hxx
@@ -147,9 +147,36 @@ namespace qak { //==============================================================
delete [] reinterpret_cast<storage_type_ *>(b_);
}
- //?vector<T> & operator = (vector<T> const & x);
- //?vector<T> & operator = (vector<T> && x);
- //?vector<T> & operator = (std::initializer_list<T> il);
+ vector<T> & operator = (vector<T> const & that)
+ {
+ if (this != &that)
+ {
+ this->clear();
+ if (that.empty())
+ {
+ this->shrink_to_fit();
+ }
+ else
+ {
+ this->reserve(that.size());
+ this->assign(that.b_, that.e_);
+ }
+ }
+
+ return *this;
+ }
+
+ vector<T> & operator = (vector<T> && src)
+ {
+ assert(this != &src);
+ this->clear();
+ this->shrink_to_fit();
+ this->swap(src);
+
+ return *this;
+ }
+
+ // vector<T> & operator = (std::initializer_list<T> il); //? TODO
template <class InputIterator>
void assign(InputIterator first, InputIterator last)
@@ -434,6 +461,16 @@ namespace qak { //==============================================================
template <class T> inline typename vector<T>::iterator end (vector<T> & v) { return v.end(); }
template <class T> inline typename vector<T>::const_iterator end (vector<T> const & v) { return v.cend(); }
+ //-----------------------------------------------------------------------------------------------------------------|
+
+ template <class T> inline void reverse_inplace(vector<T> & v)
+ {
+ typename vector<T>::size_type sz = v.size();
+ typename vector<T>::size_type left_half_end = sz/2;
+ for (typename vector<T>::size_type ix = 0; ix < left_half_end; ++ix)
+ ::std::swap<>(v[ix], v[sz - 1 - ix]);
+ }
+
} // namespace qak ====================================================================================================|
namespace std {
View
7 src/libqak/CMakeLists.txt
@@ -1,6 +1,6 @@
#=================================================================================================|
#
-# Copyright (c) 2011, Marsh Ray
+# Copyright (c) 2011-2012, Marsh Ray
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
@@ -23,6 +23,7 @@ add_library( qak STATIC
host_info.cxx
mutex.cxx
now.cxx
+ permutation.cxx
rptr.cxx
stopwatch.cxx
thread.cxx
@@ -70,6 +71,10 @@ add_executable(optional__test optional__test.cxx)
target_link_libraries(optional__test qak)
add_test(optional__test ${EXECUTABLE_OUTPUT_PATH}/optional__test)
+add_executable(permutation__test permutation__test.cxx)
+target_link_libraries(permutation__test qak)
+add_test(permutation__test ${EXECUTABLE_OUTPUT_PATH}/permutation__test)
+
add_executable(prng64__test prng64__test.cxx)
target_link_libraries(prng64__test qak)
add_test(prng64__test ${EXECUTABLE_OUTPUT_PATH}/prng64__test)
View
228 src/libqak/permutation.cxx
@@ -0,0 +1,228 @@
+// vim: set ts=4 sw=4 tw=120:
+//=====================================================================================================================|
+//
+// Copyright (c) 2012, Marsh Ray
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+// OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+//
+//=====================================================================================================================|
+//
+// permutation.cxx
+
+#include "qak/permutation.hxx"
+
+#include <cstring> // memcpy
+
+namespace qak { //=====================================================================================================|
+namespace permutation_imp {
+
+ template <int N>
+ bool index_permutation_imp<N>::empty() const
+ {
+ assert(f_.size() == r_.size());
+
+ return f_.empty();
+ }
+
+ //-----------------------------------------------------------------------------------------------------------------|
+
+ template <int N>
+ typename index_permutation_imp<N>::uint_type index_permutation_imp<N>::size() const
+ {
+ auto sz = f_.size();
+ assert(sz == r_.size());
+ assert(sz <= std::numeric_limits<uint_type>::max());
+ return static_cast<uint_type>(sz);
+ }
+
+ //-----------------------------------------------------------------------------------------------------------------|
+
+ template <int N>
+ typename index_permutation_imp<N>::uint_type index_permutation_imp<N>::f_at(uint_type ix) const
+ {
+ auto sz = f_.size();
+ assert(sz == r_.size());
+ assert(ix < sz);
+ return f_[ix];
+ }
+
+ //-----------------------------------------------------------------------------------------------------------------|
+
+ template <int N>
+ typename index_permutation_imp<N>::uint_type index_permutation_imp<N>::r_at(uint_type ix) const
+ {
+ auto sz = r_.size();
+ assert(sz == f_.size());
+ assert(ix < sz);
+ return r_[ix];
+ }
+
+ //-----------------------------------------------------------------------------------------------------------------|
+
+ template <int N>
+ void index_permutation_imp<N>::set_identity()
+ {
+ reset(size());
+ };
+
+ //-----------------------------------------------------------------------------------------------------------------|
+
+ template <int N>
+ void index_permutation_imp<N>::reset(uint_type n)
+ {
+ f_.resize(0);
+ r_.resize(0);
+ extend(n);
+ };
+
+ //-----------------------------------------------------------------------------------------------------------------|
+
+ template <int N>
+ void index_permutation_imp<N>::invert()
+ {
+ f_.swap(r_);
+ };
+
+ //-----------------------------------------------------------------------------------------------------------------|
+
+ template <int N>
+ void index_permutation_imp<N>::extend(uint_type n)
+ {
+ uint_type sz = size();
+ uint_type new_sz = sz + n;
+ f_.reserve(new_sz);
+ r_.reserve(new_sz);
+ for (uint_type ix = sz; ix < new_sz; ++ix)
+ {
+ f_.push_back(ix);
+ r_.push_back(ix);
+ }
+ }
+
+ //-----------------------------------------------------------------------------------------------------------------|
+
+ template <int N>
+ void index_permutation_imp<N>::swap_two(uint_type ix_a, uint_type ix_b)
+ {
+ uint_type jx_a = f_[ix_a]; assert(r_[jx_a] == ix_a);
+ uint_type jx_b = f_[ix_b]; assert(r_[jx_b] == ix_b);
+ f_[ix_a] = jx_b;
+ f_[ix_b] = jx_a;
+ r_[jx_a] = ix_b;
+ r_[jx_b] = ix_a;
+ }
+
+ //-----------------------------------------------------------------------------------------------------------------|
+
+ template <int N>
+ void index_permutation_imp<N>::rotate(uint_type ix_b, uint_type ix_m, uint_type ix_e)
+ {
+ assert(0 <= ix_b && ix_b <= ix_m && ix_m <= ix_e && ix_e <= f_.size());
+
+ //? OPT See the very nice section from Programming Pearls (available online) with several other
+ // algorithms benchmarked for permuting the forward vector.
+
+ uint_type sz_l = ix_m - ix_b;
+ uint_type sz_r = ix_e - ix_m;
+
+ // Early exit if there's no effective rotation.
+ if ( ! (sz_l && sz_r) )
+ return;
+
+ if (sz_l == sz_r) // left is equal to the right
+ {
+ vector_type v_tmp(&f_[ix_b], &f_[ix_b + sz_l]);
+ std::memcpy(&f_[ix_b], &f_[ix_m], sz_l*sizeof(typename vector_type::value_type));
+ std::memcpy(&f_[ix_m], &v_tmp[0], sz_l*sizeof(typename vector_type::value_type));
+ }
+ else // unequal left and right
+ {
+ if (sz_l < sz_r) // left is smaller than the right
+ {
+ vector_type v_tmp(&f_[ix_e - sz_l], &f_[ix_e - 1] + 1);
+ std::memcpy(&f_[ix_e - sz_l], &f_[ix_b], sz_l*sizeof(typename vector_type::value_type));
+ std::memmove(&f_[ix_b], &f_[ix_m], (sz_r - sz_l)*sizeof(typename vector_type::value_type));
+ std::memcpy(&f_[ix_b + sz_r - sz_l], &v_tmp[0], sz_l*sizeof(typename vector_type::value_type));
+ }
+ else // right is smaller than the left
+ {
+ vector_type v_tmp(&f_[ix_b], &f_[ix_b + sz_r]);
+ std::memcpy(&f_[ix_b], &f_[ix_m], sz_r*sizeof(typename vector_type::value_type));
+ std::memmove(&f_[ix_b + sz_r*2], &f_[ix_b + sz_r], (sz_l - sz_r)*sizeof(typename vector_type::value_type));
+ std::memcpy(&f_[ix_b + sz_r], &v_tmp[0], sz_r*sizeof(typename vector_type::value_type));
+ }
+ }
+
+ // Fix up the reverse mapping.
+ //? OPT There might be some somewhat faster ways of doing this.
+ // For example, we could track the lowest and highest reverse index seen when we do the forward rotate,
+ // and then only fix up that. Also, we could modify the reverse mapping arithmetically without referencing
+ // memory in the forward vector.
+ for (uint_type ix = ix_b; ix < ix_e; ++ix)
+ r_[f_[ix]] = ix;
+ }
+
+ //-----------------------------------------------------------------------------------------------------------------|
+
+ template <int N>
+ void index_permutation_imp<N>::square()
+ {
+ // Save f_.
+ f_.swap(r_);
+
+ // Compute f_ from saved f_.
+ uint_type sz = size();
+ for (uint_type ix = 0; ix < sz; ++ix)
+ f_[ix] = r_[r_[ix]];
+
+ // Compute r_ from f_.
+ for (uint_type ix = 0; ix < sz; ++ix)
+ r_[f_[ix]] = ix;
+ }
+
+
+ //-----------------------------------------------------------------------------------------------------------------|
+
+ template <int N>
+ void index_permutation_imp<N>::mult_by(index_permutation_imp const & that)
+ {
+ assert(this->size() == that.size());
+
+ // Save f_.
+ f_.swap(r_);
+
+ // Compute f_ from saved f_.
+ uint_type sz = size();
+ for (uint_type ix = 0; ix < sz; ++ix)
+ f_[ix] = r_[that.f_[ix]];
+
+ // Compute r_ from f_.
+ for (uint_type ix = 0; ix < sz; ++ix)
+ r_[f_[ix]] = ix;
+ }
+
+ //=================================================================================================================|
+
+ //-----------------------------------------------------------------------------------------------------------------|
+
+ //=================================================================================================================|
+
+ // Cause instantiation of the templates in this translation unit.
+ template struct index_permutation_imp<1>;
+ template struct index_permutation_imp<2>;
+ template struct index_permutation_imp<4>;
+ template struct index_permutation_imp<8>;
+
+} // namespace permutation_imp
+} // namespace qak ====================================================================================================|
+
View
582 src/libqak/permutation__test.cxx
@@ -0,0 +1,582 @@
+// vim: set ts=4 sw=4 tw=120:
+//=====================================================================================================================|
+//
+// Copyright (c) 2012, Marsh Ray
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+// OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+//
+//=====================================================================================================================|
+//
+// permutation__test.cxx
+
+#include "qak/permutation.hxx"
+
+#include "qak/test_app_pre.hxx"
+#include "qak/test_macros.hxx"
+
+namespace zzz { //=====================================================================================================|
+
+ using qak::index_permutation;
+
+ //-----------------------------------------------------------------------------------------------------------------|
+
+ template <class T> void test_index_permutation_default_ctor()
+ {
+ index_permutation<T> p;
+ QAK_verify(p.empty());
+ QAK_verify_zero(p.size());
+ }
+
+ QAKtest(index_permutation_default_ctor, "index_permutation Default construction.")
+ {
+ test_index_permutation_default_ctor<signed char>();
+ test_index_permutation_default_ctor<short int>();
+ test_index_permutation_default_ctor<int>();
+ test_index_permutation_default_ctor<long int>();
+ test_index_permutation_default_ctor<long long int>();
+ test_index_permutation_default_ctor<unsigned char>();
+ test_index_permutation_default_ctor<unsigned short int>();
+ test_index_permutation_default_ctor<unsigned int>();
+ test_index_permutation_default_ctor<unsigned long int>();
+ test_index_permutation_default_ctor<unsigned long long int>();
+ }
+
+ //-----------------------------------------------------------------------------------------------------------------|
+
+ template <class T, int cnt_N> void test_index_permutation_ctor_cnt_N()
+ {
+ index_permutation<T> p(cnt_N);
+ QAK_verify(cnt_N ? !p.empty() : p.empty());
+ QAK_verify_equal(p.size(), cnt_N);
+
+ for (T ix = 0; ix < cnt_N; ++ix) // Verify identity
+ {
+ QAK_verify_equal(p.f_at(ix), ix);
+ QAK_verify_equal(p[ix], ix); // exercises operator[]
+ QAK_verify_equal(p.at(ix), ix); // exercises at()
+ QAK_verify_equal(p.r_at(ix), ix);
+ }
+ }
+
+ template <class T> void test_index_permutation_ctor_cnt()
+ {
+ test_index_permutation_ctor_cnt_N<T, 0>();
+ test_index_permutation_ctor_cnt_N<T, 1>();
+ test_index_permutation_ctor_cnt_N<T, 2>();
+ test_index_permutation_ctor_cnt_N<T, 9>();
+ test_index_permutation_ctor_cnt_N<T, 30>();
+ }
+
+ QAKtest(index_permutation_ctor_cnt, "index_permutation construction from count.")
+ {
+ test_index_permutation_ctor_cnt<signed char>();
+ test_index_permutation_ctor_cnt<short int>();
+ test_index_permutation_ctor_cnt<int>();
+ test_index_permutation_ctor_cnt<long int>();
+ test_index_permutation_ctor_cnt<long long int>();
+ test_index_permutation_ctor_cnt<unsigned char>();
+ test_index_permutation_ctor_cnt<unsigned short int>();
+ test_index_permutation_ctor_cnt<unsigned int>();
+ test_index_permutation_ctor_cnt<unsigned long int>();
+ test_index_permutation_ctor_cnt<unsigned long long int>();
+ }
+
+ //-----------------------------------------------------------------------------------------------------------------|
+
+ template <class T> void test_index_permutation_copy_ctor()
+ {
+ index_permutation<T> p_a(1);
+ QAK_verify_equal(p_a.size(), 1);
+ QAK_verify_equal(p_a.f_at(0), 0); QAK_verify_equal(p_a.r_at(0), 0);
+
+ index_permutation<T> p_b(p_a);
+ QAK_verify_equal(p_b.size(), 1);
+ QAK_verify_equal(p_b.f_at(0), 0); QAK_verify_equal(p_b.r_at(0), 0);
+ }
+
+ QAKtest(index_permutation_copy_ctor, "index_permutation copy_ctor().")
+ {
+ test_index_permutation_copy_ctor<signed char>();
+ test_index_permutation_copy_ctor<short int>();
+ test_index_permutation_copy_ctor<int>();
+ test_index_permutation_copy_ctor<long int>();
+ test_index_permutation_copy_ctor<long long int>();
+ test_index_permutation_copy_ctor<unsigned char>();
+ test_index_permutation_copy_ctor<unsigned short int>();
+ test_index_permutation_copy_ctor<unsigned int>();
+ test_index_permutation_copy_ctor<unsigned long int>();
+ test_index_permutation_copy_ctor<unsigned long long int>();
+ }
+
+ //-----------------------------------------------------------------------------------------------------------------|
+
+ template <class T> void test_index_permutation_move_ctor()
+ {
+ index_permutation<T> p_a(1);
+ QAK_verify_equal(p_a.size(), 1);
+ QAK_verify_equal(p_a.f_at(0), 0); QAK_verify_equal(p_a.r_at(0), 0);
+
+ index_permutation<T> p_b(std::move(p_a));
+ QAK_verify_equal(p_a.size(), 0);
+ QAK_verify_equal(p_b.size(), 1);
+ QAK_verify_equal(p_b.f_at(0), 0); QAK_verify_equal(p_b.r_at(0), 0);
+ }
+
+ QAKtest(index_permutation_move_ctor, "index_permutation move_ctor().")
+ {
+ test_index_permutation_move_ctor<signed char>();
+ test_index_permutation_move_ctor<short int>();
+ test_index_permutation_move_ctor<int>();
+ test_index_permutation_move_ctor<long int>();
+ test_index_permutation_move_ctor<long long int>();
+ test_index_permutation_move_ctor<unsigned char>();
+ test_index_permutation_move_ctor<unsigned short int>();
+ test_index_permutation_move_ctor<unsigned int>();
+ test_index_permutation_move_ctor<unsigned long int>();
+ test_index_permutation_move_ctor<unsigned long long int>();
+ }
+
+ //-----------------------------------------------------------------------------------------------------------------|
+
+ template <class T> void test_index_permutation_assign()
+ {
+ index_permutation<T> p_a;
+ index_permutation<T> p_b(1);
+
+ QAK_verify_equal(p_a.size(), 0);
+
+ QAK_verify_equal(p_b.size(), 1);
+ QAK_verify_equal(p_b.f_at(0), 0); QAK_verify_equal(p_b.r_at(0), 0);
+
+ p_a = p_b;
+
+ QAK_verify_equal(p_a.size(), 1);
+ QAK_verify_equal(p_a.f_at(0), 0); QAK_verify_equal(p_a.r_at(0), 0);
+
+ QAK_verify_equal(p_b.size(), 1);
+ QAK_verify_equal(p_b.f_at(0), 0); QAK_verify_equal(p_b.r_at(0), 0);
+ }
+
+ QAKtest(index_permutation_assign, "index_permutation assign().")
+ {
+ test_index_permutation_assign<signed char>();
+ test_index_permutation_assign<short int>();
+ test_index_permutation_assign<int>();
+ test_index_permutation_assign<long int>();
+ test_index_permutation_assign<long long int>();
+ test_index_permutation_assign<unsigned char>();
+ test_index_permutation_assign<unsigned short int>();
+ test_index_permutation_assign<unsigned int>();
+ test_index_permutation_assign<unsigned long int>();
+ test_index_permutation_assign<unsigned long long int>();
+ }
+
+ //-----------------------------------------------------------------------------------------------------------------|
+
+ template <class T> void test_index_permutation_move_assign()
+ {
+ index_permutation<T> p_a;
+ index_permutation<T> p_b(1);
+
+ QAK_verify_equal(p_a.size(), 0);
+
+ QAK_verify_equal(p_b.size(), 1);
+ QAK_verify_equal(p_b.f_at(0), 0); QAK_verify_equal(p_b.r_at(0), 0);
+
+ p_a = std::move(p_b);
+
+ QAK_verify_equal(p_a.size(), 1);
+ QAK_verify_equal(p_a.f_at(0), 0); QAK_verify_equal(p_a.r_at(0), 0);
+
+ QAK_verify_equal(p_b.size(), 0);
+ }
+
+ QAKtest(index_permutation_move_assign, "index_permutation move_assign().")
+ {
+ test_index_permutation_move_assign<signed char>();
+ test_index_permutation_move_assign<short int>();
+ test_index_permutation_move_assign<int>();
+ test_index_permutation_move_assign<long int>();
+ test_index_permutation_move_assign<long long int>();
+ test_index_permutation_move_assign<unsigned char>();
+ test_index_permutation_move_assign<unsigned short int>();
+ test_index_permutation_move_assign<unsigned int>();
+ test_index_permutation_move_assign<unsigned long int>();
+ test_index_permutation_move_assign<unsigned long long int>();
+ }
+
+ //-----------------------------------------------------------------------------------------------------------------|
+
+ template <class T> void test_index_permutation_equality()
+ {
+ for (unsigned n = 0; n < 20; ++n)
+ {
+ index_permutation<T> p_a(n);
+ index_permutation<T> p_b(p_a);
+ QAK_verify(p_a == p_b);
+ QAK_verify(p_b == p_a);
+ QAK_verify( ! (p_a != p_b) );
+ QAK_verify( ! (p_b != p_a) );
+ if (2 <= n)
+ {
+ p_b.swap_two(0, 1);
+ QAK_verify(p_a != p_b);
+ QAK_verify(p_b != p_a);
+ }
+ }
+ }
+
+ QAKtest(index_permutation_equality, "index_permutation equality().")
+ {
+ test_index_permutation_equality<signed char>();
+ test_index_permutation_equality<short int>();
+ test_index_permutation_equality<int>();
+ test_index_permutation_equality<long int>();
+ test_index_permutation_equality<long long int>();
+ test_index_permutation_equality<unsigned char>();
+ test_index_permutation_equality<unsigned short int>();
+ test_index_permutation_equality<unsigned int>();
+ test_index_permutation_equality<unsigned long int>();
+ test_index_permutation_equality<unsigned long long int>();
+ }
+
+ //-----------------------------------------------------------------------------------------------------------------|
+
+ template <class T> void test_index_permutation_swap_two()
+ {
+ {
+ index_permutation<T> p(1);
+ QAK_verify_equal(p.f_at(0), 0); QAK_verify_equal(p.r_at(0), 0);
+ p.swap_two(0, 0);
+ QAK_verify_equal(p.f_at(0), 0); QAK_verify_equal(p.r_at(0), 0);
+ } {
+ index_permutation<T> p(2);
+ QAK_verify_equal(p.f_at(0), 0); QAK_verify_equal(p.r_at(0), 0);
+ QAK_verify_equal(p.f_at(1), 1); QAK_verify_equal(p.r_at(1), 1);
+ p.swap_two(0, 1);
+ QAK_verify_equal(p.f_at(0), 1); QAK_verify_equal(p.r_at(0), 1);
+ QAK_verify_equal(p.f_at(1), 0); QAK_verify_equal(p.r_at(1), 0);
+ p.swap_two(0, 1);
+ QAK_verify_equal(p.f_at(0), 0); QAK_verify_equal(p.r_at(0), 0);
+ QAK_verify_equal(p.f_at(1), 1); QAK_verify_equal(p.r_at(1), 1);
+ } {
+ index_permutation<T> p(3);
+ QAK_verify_equal(p.f_at(0), 0); QAK_verify_equal(p.r_at(0), 0);
+ QAK_verify_equal(p.f_at(1), 1); QAK_verify_equal(p.r_at(1), 1);
+ QAK_verify_equal(p.f_at(2), 2); QAK_verify_equal(p.r_at(2), 2);
+ p.swap_two(1, 2);
+ QAK_verify_equal(p.f_at(0), 0); QAK_verify_equal(p.r_at(0), 0);
+ QAK_verify_equal(p.f_at(1), 2); QAK_verify_equal(p.r_at(1), 2);
+ QAK_verify_equal(p.f_at(2), 1); QAK_verify_equal(p.r_at(2), 1);
+ p.swap_two(0, 2);
+ QAK_verify_equal(p.f_at(0), 1); QAK_verify_equal(p.r_at(0), 2);
+ QAK_verify_equal(p.f_at(1), 2); QAK_verify_equal(p.r_at(1), 0);
+ QAK_verify_equal(p.f_at(2), 0); QAK_verify_equal(p.r_at(2), 1);
+ }
+ }
+
+ QAKtest(index_permutation_swap_two, "index_permutation swap_two().")
+ {
+ test_index_permutation_swap_two<signed char>();
+ test_index_permutation_swap_two<short int>();
+ test_index_permutation_swap_two<int>();
+ test_index_permutation_swap_two<long int>();
+ test_index_permutation_swap_two<long long int>();
+ test_index_permutation_swap_two<unsigned char>();
+ test_index_permutation_swap_two<unsigned short int>();
+ test_index_permutation_swap_two<unsigned int>();
+ test_index_permutation_swap_two<unsigned long int>();
+ test_index_permutation_swap_two<unsigned long long int>();
+ }
+
+ //-----------------------------------------------------------------------------------------------------------------|
+
+ template <class T> void test_index_permutation_extend()
+ {
+ {
+ index_permutation<T> p(0);
+ p.extend(1);
+ QAK_verify_equal(p.size(), 1);
+ QAK_verify_equal(p.f_at(0), 0); QAK_verify_equal(p.r_at(0), 0);
+ p.extend(2);
+ QAK_verify_equal(p.size(), 3);
+ QAK_verify_equal(p.f_at(0), 0); QAK_verify_equal(p.r_at(0), 0);
+ QAK_verify_equal(p.f_at(1), 1); QAK_verify_equal(p.r_at(1), 1);
+ QAK_verify_equal(p.f_at(2), 2); QAK_verify_equal(p.r_at(2), 2);
+ p.swap_two(1, 2);
+ QAK_verify_equal(p.f_at(0), 0); QAK_verify_equal(p.r_at(0), 0);
+ QAK_verify_equal(p.f_at(1), 2); QAK_verify_equal(p.r_at(1), 2);
+ QAK_verify_equal(p.f_at(2), 1); QAK_verify_equal(p.r_at(2), 1);
+ p.extend(2);
+ QAK_verify_equal(p.size(), 5);
+ QAK_verify_equal(p.f_at(0), 0); QAK_verify_equal(p.r_at(0), 0);
+ QAK_verify_equal(p.f_at(1), 2); QAK_verify_equal(p.r_at(1), 2);
+ QAK_verify_equal(p.f_at(2), 1); QAK_verify_equal(p.r_at(2), 1);
+ QAK_verify_equal(p.f_at(3), 3); QAK_verify_equal(p.r_at(3), 3);
+ QAK_verify_equal(p.f_at(4), 4); QAK_verify_equal(p.r_at(4), 4);
+ }
+ }
+
+ QAKtest(index_permutation_extend, "index_permutation extend().")
+ {
+ test_index_permutation_extend<signed char>();
+ test_index_permutation_extend<short int>();
+ test_index_permutation_extend<int>();
+ test_index_permutation_extend<long int>();
+ test_index_permutation_extend<long long int>();
+ test_index_permutation_extend<unsigned char>();
+ test_index_permutation_extend<unsigned short int>();
+ test_index_permutation_extend<unsigned int>();
+ test_index_permutation_extend<unsigned long int>();
+ test_index_permutation_extend<unsigned long long int>();
+ }
+
+ //-----------------------------------------------------------------------------------------------------------------|
+
+ template <class T> void test_index_permutation_swap()
+ {
+ index_permutation<T> p_a;
+ QAK_verify_equal(p_a.size(), 0);
+
+ index_permutation<T> p_b(1);
+ QAK_verify_equal(p_b.size(), 1);
+ QAK_verify_equal(p_b.f_at(0), 0); QAK_verify_equal(p_b.r_at(0), 0);
+
+ std::swap(p_a, p_b);
+
+ QAK_verify_equal(p_a.size(), 1);
+ QAK_verify_equal(p_a.f_at(0), 0); QAK_verify_equal(p_a.r_at(0), 0);
+
+ QAK_verify_equal(p_b.size(), 0);
+ }
+
+ QAKtest(index_permutation_swap, "index_permutation swap().")
+ {
+ test_index_permutation_swap<signed char>();
+ test_index_permutation_swap<short int>();
+ test_index_permutation_swap<int>();
+ test_index_permutation_swap<long int>();
+ test_index_permutation_swap<long long int>();
+ test_index_permutation_swap<unsigned char>();
+ test_index_permutation_swap<unsigned short int>();
+ test_index_permutation_swap<unsigned int>();
+ test_index_permutation_swap<unsigned long int>();
+ test_index_permutation_swap<unsigned long long int>();
+ }
+
+ //-----------------------------------------------------------------------------------------------------------------|
+
+ template <class T> void test_index_permutation_rotate()
+ {
+ {
+ index_permutation<T> p(3);
+ QAK_verify_equal(p.f_at(0), 0); QAK_verify_equal(p.r_at(0), 0);
+ QAK_verify_equal(p.f_at(1), 1); QAK_verify_equal(p.r_at(1), 1);
+ QAK_verify_equal(p.f_at(2), 2); QAK_verify_equal(p.r_at(2), 2);
+
+ p.rotate(0, 0, 0); // no-op rotate
+
+ QAK_verify_equal(p.f_at(0), 0); QAK_verify_equal(p.r_at(0), 0);
+ QAK_verify_equal(p.f_at(1), 1); QAK_verify_equal(p.r_at(1), 1);
+ QAK_verify_equal(p.f_at(2), 2); QAK_verify_equal(p.r_at(2), 2);
+
+ p.rotate(0, 1, 2);
+
+ QAK_verify_equal(p.f_at(0), 1); QAK_verify_equal(p.r_at(0), 1);
+ QAK_verify_equal(p.f_at(1), 0); QAK_verify_equal(p.r_at(1), 0);
+ QAK_verify_equal(p.f_at(2), 2); QAK_verify_equal(p.r_at(2), 2);
+
+ p.rotate(0, 1, 2); // take us back to starting pattern
+
+ QAK_verify_equal(p.f_at(0), 0); QAK_verify_equal(p.r_at(0), 0);
+ QAK_verify_equal(p.f_at(1), 1); QAK_verify_equal(p.r_at(1), 1);
+ QAK_verify_equal(p.f_at(2), 2); QAK_verify_equal(p.r_at(2), 2);
+ } {
+ // Test clockwise-by-1 rotations.
+ for (unsigned n = 0; n < 10; ++n)
+ {
+ index_permutation<T> const p_ref(n);
+ index_permutation<T> p_a = p_ref;
+ for (unsigned i = 0; true; ++i)
+ {
+ if (i == 0 || i == n) QAK_verify(p_a == p_ref);
+ else QAK_verify(p_a != p_ref);
+
+ if (i == n) break;
+
+ p_a.rotate(0, 1, n);
+ }
+ }
+ } {
+ // Test counterclockwise-by-1 rotations.
+ for (unsigned n = 0; n < 10; ++n)
+ {
+ index_permutation<T> const p_ref(n);
+ index_permutation<T> p_a = p_ref;
+ for (unsigned i = 0; true; ++i)
+ {
+ if (i == 0 || i == n) QAK_verify(p_a == p_ref);
+ else QAK_verify(p_a != p_ref);
+
+ if (i == n) break;
+
+ p_a.rotate(0, n - 1, n);
+ }
+ }
+ } {
+ // Test counterclockwise-by-25 rotations.
+ index_permutation<T> const p_ref(100);
+ index_permutation<T> p_a = p_ref;
+ QAK_verify(p_a == p_ref);
+ p_a.rotate(0, 25, 100);
+ QAK_verify(p_a != p_ref);
+ p_a.rotate(0, 25, 100);
+ QAK_verify(p_a != p_ref);
+ p_a.rotate(0, 25, 100);
+ QAK_verify(p_a != p_ref);
+ p_a.rotate(0, 25, 100);
+ QAK_verify(p_a == p_ref);
+ }
+ }
+
+ QAKtest(index_permutation_rotate, "index_permutation rotate().")
+ {
+ test_index_permutation_rotate<signed char>();
+ test_index_permutation_rotate<short int>();
+ test_index_permutation_rotate<int>();
+ test_index_permutation_rotate<long int>();
+ test_index_permutation_rotate<long long int>();
+ test_index_permutation_rotate<unsigned char>();
+ test_index_permutation_rotate<unsigned short int>();
+ test_index_permutation_rotate<unsigned int>();
+ test_index_permutation_rotate<unsigned long int>();
+ test_index_permutation_rotate<unsigned long long int>();
+ }
+
+ //-----------------------------------------------------------------------------------------------------------------|
+
+ template <class T> void test_index_permutation_square()
+ {
+ {
+ index_permutation<T> p_ref(0);
+ index_permutation<T> p_a(p_ref);
+ QAK_verify(p_a == p_ref);
+ p_a.square();
+ QAK_verify(p_a == p_ref);
+ } {
+ index_permutation<T> p_ref(1);
+ index_permutation<T> p_a(p_ref);
+ QAK_verify(p_a == p_ref);
+ p_a.square();
+ QAK_verify(p_a == p_ref);
+ } {
+ index_permutation<T> p_ref(2);
+ index_permutation<T> p_a(p_ref);
+ QAK_verify(p_a == p_ref);
+ p_a.square();
+ QAK_verify(p_a == p_ref);
+ } {
+ index_permutation<T> p(3);
+ p.swap_two(1, 2);
+ QAK_verify_equal(p.f_at(0), 0); QAK_verify_equal(p.r_at(0), 0);
+ QAK_verify_equal(p.f_at(1), 2); QAK_verify_equal(p.r_at(1), 2);
+ QAK_verify_equal(p.f_at(2), 1); QAK_verify_equal(p.r_at(2), 1);
+ p.square();
+ QAK_verify_equal(p.f_at(0), 0); QAK_verify_equal(p.r_at(0), 0);
+ QAK_verify_equal(p.f_at(1), 1); QAK_verify_equal(p.r_at(1), 1);
+ QAK_verify_equal(p.f_at(2), 2); QAK_verify_equal(p.r_at(2), 2);
+ } {
+ // Test squaring of an involution, which should take us back to the identity transform
+ index_permutation<T> p_ref(10);
+ index_permutation<T> p_a(p_ref);
+ QAK_verify(p_a == p_ref);
+ p_a.swap_two(0, 5);
+ p_a.swap_two(1, 3);
+ p_a.swap_two(2, 7);
+ p_a.swap_two(4, 6);
+ p_a.swap_two(8, 9);
+ QAK_verify(p_a != p_ref);
+ p_a.square();
+ QAK_verify(p_a == p_ref);
+ } {
+ }
+ }
+
+ QAKtest(index_permutation_square, "index_permutation square().")
+ {
+ test_index_permutation_square<signed char>();
+ test_index_permutation_square<short int>();
+ test_index_permutation_square<int>();
+ test_index_permutation_square<long int>();
+ test_index_permutation_square<long long int>();
+ test_index_permutation_square<unsigned char>();
+ test_index_permutation_square<unsigned short int>();
+ test_index_permutation_square<unsigned int>();
+ test_index_permutation_square<unsigned long int>();
+ test_index_permutation_square<unsigned long long int>();
+ }
+
+ //-----------------------------------------------------------------------------------------------------------------|
+
+ template <class T> void test_index_permutation_mult()
+ {
+ index_permutation<T> const p_ref(3);
+ {
+ index_permutation<T> p_a(p_ref);
+ index_permutation<T> p_b(p_ref);
+ p_a *= p_b;
+ QAK_verify(p_a == p_ref);
+ } {
+ index_permutation<T> p_a(p_ref);
+ index_permutation<T> p_b(p_ref);
+ index_permutation<T> p_c = p_a*p_b;
+ QAK_verify(p_a == p_ref);
+ } {
+ index_permutation<T> p_a(p_ref);
+ p_a.swap_two(0, 1);
+ QAK_verify_equal(p_a.f_at(0), 1); QAK_verify_equal(p_a.r_at(0), 1);
+ QAK_verify_equal(p_a.f_at(1), 0); QAK_verify_equal(p_a.r_at(1), 0);
+ QAK_verify_equal(p_a.f_at(2), 2); QAK_verify_equal(p_a.r_at(2), 2);
+
+ index_permutation<T> p_b(p_ref);
+ p_b.swap_two(1, 2);
+ QAK_verify_equal(p_b.f_at(0), 0); QAK_verify_equal(p_b.r_at(0), 0);
+ QAK_verify_equal(p_b.f_at(1), 2); QAK_verify_equal(p_b.r_at(1), 2);
+ QAK_verify_equal(p_b.f_at(2), 1); QAK_verify_equal(p_b.r_at(2), 1);
+
+ index_permutation<T> p_c = p_a*p_b;
+ QAK_verify_equal(p_c.f_at(0), 1); QAK_verify_equal(p_c.r_at(0), 2);
+ QAK_verify_equal(p_c.f_at(1), 2); QAK_verify_equal(p_c.r_at(1), 0);
+ QAK_verify_equal(p_c.f_at(2), 0); QAK_verify_equal(p_c.r_at(2), 1);
+ }
+ }
+
+ QAKtest(index_permutation_mult, "index_permutation mult().")
+ {
+ test_index_permutation_mult<signed char>();
+ test_index_permutation_mult<short int>();
+ test_index_permutation_mult<int>();
+ test_index_permutation_mult<long int>();
+ test_index_permutation_mult<long long int>();
+ test_index_permutation_mult<unsigned char>();
+ test_index_permutation_mult<unsigned short int>();
+ test_index_permutation_mult<unsigned int>();
+ test_index_permutation_mult<unsigned long int>();
+ test_index_permutation_mult<unsigned long long int>();
+ }
+
+ //-----------------------------------------------------------------------------------------------------------------|
+
+
+} // namespace zzz ====================================================================================================|
+#include "qak/test_app_post.hxx"
View
27 src/libqak/vector__test.cxx
@@ -116,7 +116,7 @@ namespace zzz { //==============================================================
typedef qak::vector<unsigned> v_us_t;
typedef v_us_t::size_type v_us_size_t;
- // Resizing downwards
+
qak::vector<unsigned> v;
for (unsigned n = 0; n < 200; ++n)
v.push_back(n);
@@ -141,5 +141,30 @@ namespace zzz { //==============================================================
QAK_verify( v.empty() );
}
+ QAKtest_anon() // copy assignment
+ {
+ qak::vector<unsigned> v_a(std::size_t(1000), 1u);
+ for (unsigned n = 0; n < 1000; ++n) QAK_verify( v_a[n] == 1 );
+
+ qak::vector<unsigned> v_b;
+ v_b = v_a;
+
+ for (unsigned n = 0; n < 1000; ++n) QAK_verify( v_b[n] == 1 );
+ }
+
+ QAKtest_anon() // move assignment
+ {
+ qak::vector<unsigned> v_a(std::size_t(1000), 1u);
+ for (unsigned n = 0; n < 1000; ++n) QAK_verify( v_a[n] == 1 );
+
+ qak::vector<unsigned> v_b;
+ v_b = std::move(v_a);
+
+ QAK_verify( v_a.empty() );
+ for (unsigned n = 0; n < 1000; ++n) QAK_verify( v_b[n] == 1 );
+ }
+
+ //? test move assignment
+
} // namespace zzz ====================================================================================================|
#include "qak/test_app_post.hxx"

No commit comments for this range

Something went wrong with that request. Please try again.