diff options
Diffstat (limited to 'src/boost/libs/hana/test/numeric/main.hpp')
-rw-r--r-- | src/boost/libs/hana/test/numeric/main.hpp | 511 |
1 files changed, 511 insertions, 0 deletions
diff --git a/src/boost/libs/hana/test/numeric/main.hpp b/src/boost/libs/hana/test/numeric/main.hpp new file mode 100644 index 00000000..f092cdee --- /dev/null +++ b/src/boost/libs/hana/test/numeric/main.hpp @@ -0,0 +1,511 @@ +// Copyright Louis Dionne 2013-2017 +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#include <boost/hana/and.hpp> +#include <boost/hana/assert.hpp> +#include <boost/hana/comparing.hpp> +#include <boost/hana/div.hpp> +#include <boost/hana/equal.hpp> +#include <boost/hana/eval_if.hpp> +#include <boost/hana/greater.hpp> +#include <boost/hana/greater_equal.hpp> +#include <boost/hana/if.hpp> +#include <boost/hana/less.hpp> +#include <boost/hana/less_equal.hpp> +#include <boost/hana/max.hpp> +#include <boost/hana/min.hpp> +#include <boost/hana/minus.hpp> +#include <boost/hana/mod.hpp> +#include <boost/hana/mult.hpp> +#include <boost/hana/negate.hpp> +#include <boost/hana/not.hpp> +#include <boost/hana/not_equal.hpp> +#include <boost/hana/one.hpp> +#include <boost/hana/or.hpp> +#include <boost/hana/ordering.hpp> +#include <boost/hana/plus.hpp> +#include <boost/hana/power.hpp> +#include <boost/hana/tuple.hpp> +#include <boost/hana/while.hpp> +#include <boost/hana/zero.hpp> + +#include <laws/base.hpp> +#include <laws/comparable.hpp> +#include <laws/euclidean_ring.hpp> +#include <laws/group.hpp> +#include <laws/logical.hpp> +#include <laws/monoid.hpp> +#include <laws/orderable.hpp> +#include <support/cnumeric.hpp> +#include <support/numeric.hpp> + +#include <cstdlib> +#include <vector> +namespace hana = boost::hana; + + +struct invalid { + template <typename T> + operator T const() { std::abort(); } +}; + +int main() { + ////////////////////////////////////////////////////////////////////////// + // Comparable + ////////////////////////////////////////////////////////////////////////// + { + hana::test::_injection<0> f{}; + auto x = numeric(1); + auto y = numeric(2); + + // equal + { + BOOST_HANA_CONSTEXPR_CHECK(hana::equal(x, x)); + BOOST_HANA_CONSTEXPR_CHECK(hana::not_(hana::equal(x, y))); + } + + // not_equal + { + BOOST_HANA_CONSTEXPR_CHECK(hana::not_equal(x, y)); + BOOST_HANA_CONSTEXPR_CHECK(hana::not_(hana::not_equal(x, x))); + } + + // comparing + { + BOOST_HANA_CONSTEXPR_CHECK(hana::equal( + hana::comparing(f)(x, x), + hana::equal(f(x), f(x)) + )); + + BOOST_HANA_CONSTEXPR_CHECK(hana::equal( + hana::comparing(f)(x, y), + hana::equal(f(x), f(y)) + )); + } + } + + ////////////////////////////////////////////////////////////////////////// + // Orderable + ////////////////////////////////////////////////////////////////////////// + { + auto ord = numeric; + + // _injection is also monotonic + hana::test::_injection<0> f{}; + + // less + { + BOOST_HANA_CONSTEXPR_CHECK(hana::less(ord(0), ord(1))); + BOOST_HANA_CONSTEXPR_CHECK(hana::not_(hana::less(ord(0), ord(0)))); + BOOST_HANA_CONSTEXPR_CHECK(hana::not_(hana::less(ord(1), ord(0)))); + } + + // less_equal + { + BOOST_HANA_CONSTEXPR_CHECK(hana::less_equal(ord(0), ord(1))); + BOOST_HANA_CONSTEXPR_CHECK(hana::less_equal(ord(0), ord(0))); + BOOST_HANA_CONSTEXPR_CHECK(hana::not_(hana::less_equal(ord(1), ord(0)))); + } + + // greater_equal + { + BOOST_HANA_CONSTEXPR_CHECK(hana::greater_equal(ord(1), ord(0))); + BOOST_HANA_CONSTEXPR_CHECK(hana::greater_equal(ord(0), ord(0))); + BOOST_HANA_CONSTEXPR_CHECK(hana::not_(hana::greater_equal(ord(0), ord(1)))); + } + + // greater + { + BOOST_HANA_CONSTEXPR_CHECK(hana::greater(ord(1), ord(0))); + BOOST_HANA_CONSTEXPR_CHECK(hana::not_(hana::greater(ord(0), ord(0)))); + BOOST_HANA_CONSTEXPR_CHECK(hana::not_(hana::greater(ord(0), ord(1)))); + } + + // max + { + BOOST_HANA_CONSTEXPR_CHECK(hana::equal( + hana::max(ord(0), ord(0)), ord(0) + )); + BOOST_HANA_CONSTEXPR_CHECK(hana::equal( + hana::max(ord(1), ord(0)), ord(1) + )); + BOOST_HANA_CONSTEXPR_CHECK(hana::equal( + hana::max(ord(0), ord(1)), ord(1) + )); + } + + // min + { + BOOST_HANA_CONSTEXPR_CHECK(hana::equal( + hana::min(ord(0), ord(0)), + ord(0) + )); + BOOST_HANA_CONSTEXPR_CHECK(hana::equal( + hana::min(ord(1), ord(0)), + ord(0) + )); + BOOST_HANA_CONSTEXPR_CHECK(hana::equal( + hana::min(ord(0), ord(1)), + ord(0) + )); + } + + // ordering + { + BOOST_HANA_CONSTEXPR_CHECK(hana::equal( + hana::ordering(f)(ord(1), ord(0)), + hana::less(f(ord(1)), f(ord(0))) + )); + + BOOST_HANA_CONSTEXPR_CHECK(hana::equal( + hana::ordering(f)(ord(0), ord(1)), + hana::less(f(ord(0)), f(ord(1))) + )); + + BOOST_HANA_CONSTEXPR_CHECK(hana::equal( + hana::ordering(f)(ord(0), ord(0)), + hana::less(f(ord(0)), f(ord(0))) + )); + } + } + + ////////////////////////////////////////////////////////////////////////// + // Monoid + ////////////////////////////////////////////////////////////////////////// + { + constexpr int x = 2, y = 3; + + // zero + { + BOOST_HANA_CONSTEXPR_CHECK(hana::equal( + hana::zero<Numeric>(), numeric(0) + )); + } + + // plus + { + BOOST_HANA_CONSTEXPR_CHECK(hana::equal( + hana::plus(numeric(x), numeric(y)), + numeric(x + y) + )); + } + } + + ////////////////////////////////////////////////////////////////////////// + // Group + ////////////////////////////////////////////////////////////////////////// + { + constexpr int x = 2, y = 3; + + // minus + { + BOOST_HANA_CONSTEXPR_CHECK(hana::equal( + hana::minus(numeric(x), numeric(y)), + numeric(x - y) + )); + } + + // negate + { + BOOST_HANA_CONSTEXPR_CHECK(hana::equal( + hana::negate(numeric(x)), + numeric(-x) + )); + } + } + + ////////////////////////////////////////////////////////////////////////// + // Ring + ////////////////////////////////////////////////////////////////////////// + { + constexpr int x = 2, y = 3; + + // one + { + BOOST_HANA_CONSTEXPR_CHECK(hana::equal( + hana::one<Numeric>(), + numeric(1) + )); + } + + // mult + { + BOOST_HANA_CONSTEXPR_CHECK(hana::equal( + hana::mult(numeric(x), numeric(y)), + numeric(x * y) + )); + } + + // power + { + BOOST_HANA_CONSTEXPR_CHECK(hana::equal( + hana::power(numeric(x), hana::zero<CNumeric<int>>()), + hana::one<Numeric>() + )); + + BOOST_HANA_CONSTEXPR_CHECK(hana::equal( + hana::power(numeric(x), hana::one<CNumeric<int>>()), + numeric(x) + )); + + BOOST_HANA_CONSTEXPR_CHECK(hana::equal( + hana::power(numeric(x), cnumeric<int, 2>), + hana::mult(numeric(x), numeric(x)) + )); + + BOOST_HANA_CONSTEXPR_CHECK(hana::equal( + hana::power(numeric(x), cnumeric<int, 3>), + hana::mult(hana::mult(numeric(x), numeric(x)), numeric(x)) + )); + } + } + + ////////////////////////////////////////////////////////////////////////// + // EuclideanRing + ////////////////////////////////////////////////////////////////////////// + { + constexpr int x = 6, y = 3, z = 4; + + // div + { + BOOST_HANA_CONSTEXPR_CHECK(hana::equal( + hana::div(numeric(x), numeric(y)), + numeric(x / y) + )); + + BOOST_HANA_CONSTEXPR_CHECK(hana::equal( + hana::div(numeric(x), numeric(z)), + numeric(x/ z) + )); + } + + // mod + { + BOOST_HANA_CONSTEXPR_CHECK(hana::equal( + hana::mod(numeric(x), numeric(y)), + numeric(x % y) + )); + + BOOST_HANA_CONSTEXPR_CHECK(hana::equal( + hana::mod(numeric(x), numeric(z)), + numeric(x % z) + )); + } + } + + ////////////////////////////////////////////////////////////////////////// + // Logical + ////////////////////////////////////////////////////////////////////////// + { + auto logical = numeric; + auto comparable = numeric; + + // not_ + { + BOOST_HANA_CONSTEXPR_CHECK(hana::equal( + hana::not_(logical(true)), + logical(false) + )); + } + + // and_ + { + BOOST_HANA_CONSTEXPR_CHECK(hana::equal( + hana::and_(logical(true)), + logical(true) + )); + BOOST_HANA_CONSTEXPR_CHECK(hana::equal( + hana::and_(logical(false)), + logical(false) + )); + + BOOST_HANA_CONSTEXPR_CHECK(hana::equal( + hana::and_(logical(true), logical(true)), + logical(true) + )); + BOOST_HANA_CONSTEXPR_CHECK(hana::equal( + hana::and_(logical(true), logical(false)), + logical(false) + )); + BOOST_HANA_CONSTEXPR_CHECK(hana::equal( + hana::and_(logical(false), invalid{}), + logical(false) + )); + + BOOST_HANA_CONSTEXPR_CHECK(hana::equal( + hana::and_(logical(true), logical(true), logical(true)), + logical(true) + )); + BOOST_HANA_CONSTEXPR_CHECK(hana::equal( + hana::and_(logical(true), logical(true), logical(false)), + logical(false) + )); + BOOST_HANA_CONSTEXPR_CHECK(hana::equal( + hana::and_(logical(true), logical(false), invalid{}), + logical(false) + )); + BOOST_HANA_CONSTEXPR_CHECK(hana::equal( + hana::and_(logical(false), invalid{}, invalid{}), + logical(false) + )); + } + + // or_ + { + BOOST_HANA_CONSTEXPR_CHECK(hana::equal( + hana::or_(logical(true)), + logical(true) + )); + BOOST_HANA_CONSTEXPR_CHECK(hana::equal( + hana::or_(logical(false)), + logical(false) + )); + + BOOST_HANA_CONSTEXPR_CHECK(hana::equal( + hana::or_(logical(false), logical(false)), + logical(false) + )); + BOOST_HANA_CONSTEXPR_CHECK(hana::equal( + hana::or_(logical(false), logical(true)), + logical(true) + )); + BOOST_HANA_CONSTEXPR_CHECK(hana::equal( + hana::or_(logical(true), invalid{}), + logical(true) + )); + + BOOST_HANA_CONSTEXPR_CHECK(hana::equal( + hana::or_(logical(false), logical(false), logical(false)), + logical(false) + )); + BOOST_HANA_CONSTEXPR_CHECK(hana::equal( + hana::or_(logical(false), logical(false), logical(true)), + logical(true) + )); + BOOST_HANA_CONSTEXPR_CHECK(hana::equal( + hana::or_(logical(false), logical(true), invalid{}), + logical(true) + )); + BOOST_HANA_CONSTEXPR_CHECK(hana::equal( + hana::or_(logical(true), invalid{}, invalid{}), + logical(true) + )); + } + + // if_ + { + BOOST_HANA_CONSTEXPR_CHECK(hana::equal( + hana::if_(logical(true), comparable(0), comparable(1)), + comparable(0) + )); + + BOOST_HANA_CONSTEXPR_CHECK(hana::equal( + hana::if_(logical(false), comparable(0), comparable(1)), + comparable(1) + )); + } + + // eval_if + { + auto t = [=](auto) { return comparable(0); }; + auto e = [=](auto) { return comparable(1); }; + + BOOST_HANA_CONSTEXPR_CHECK(hana::equal( + hana::eval_if(logical(true), t, e), + comparable(0) + )); + + BOOST_HANA_CONSTEXPR_CHECK(hana::equal( + hana::eval_if(logical(false), t, e), + comparable(1) + )); + } + + // while_ + { + auto smaller_than = [](auto n) { + return [n](auto v) { return v.size() < n; }; + }; + auto f = [](auto v) { + v.push_back(v.size()); + return v; + }; + + BOOST_HANA_RUNTIME_CHECK(hana::equal( + hana::while_(smaller_than(0u), std::vector<int>{}, f), + std::vector<int>{} + )); + + BOOST_HANA_RUNTIME_CHECK(hana::equal( + hana::while_(smaller_than(1u), std::vector<int>{}, f), + std::vector<int>{0} + )); + + BOOST_HANA_RUNTIME_CHECK(hana::equal( + hana::while_(smaller_than(2u), std::vector<int>{}, f), + std::vector<int>{0, 1} + )); + + BOOST_HANA_RUNTIME_CHECK(hana::equal( + hana::while_(smaller_than(3u), std::vector<int>{}, f), + std::vector<int>{0, 1, 2} + )); + + BOOST_HANA_RUNTIME_CHECK(hana::equal( + hana::while_(smaller_than(4u), std::vector<int>{}, f), + std::vector<int>{0, 1, 2, 3} + )); + + // Make sure it can be called with an lvalue state: + std::vector<int> v{}; + BOOST_HANA_RUNTIME_CHECK(hana::equal( + hana::while_(smaller_than(4u), v, f), + std::vector<int>{0, 1, 2, 3} + )); + } + + // while_ + { + auto less_than = [](auto n) { + return [n](auto v) { return v.size() < n; }; + }; + auto f = [](auto v) { + v.push_back(v.size()); + return v; + }; + + BOOST_HANA_RUNTIME_CHECK(hana::equal( + hana::while_(less_than(0u), std::vector<int>{}, f), + std::vector<int>{} + )); + + BOOST_HANA_RUNTIME_CHECK(hana::equal( + hana::while_(less_than(1u), std::vector<int>{}, f), + std::vector<int>{0} + )); + + BOOST_HANA_RUNTIME_CHECK(hana::equal( + hana::while_(less_than(2u), std::vector<int>{}, f), + std::vector<int>{0, 1} + )); + + BOOST_HANA_RUNTIME_CHECK(hana::equal( + hana::while_(less_than(3u), std::vector<int>{}, f), + std::vector<int>{0, 1, 2} + )); + + BOOST_HANA_RUNTIME_CHECK(hana::equal( + hana::while_(less_than(4u), std::vector<int>{}, f), + std::vector<int>{0, 1, 2, 3} + )); + + // Make sure it can be called with an lvalue state: + std::vector<int> v{}; + BOOST_HANA_RUNTIME_CHECK(hana::equal( + hana::while_(less_than(4u), v, f), + std::vector<int>{0, 1, 2, 3} + )); + } + } +} |