123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511 |
- // 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}
- ));
- }
- }
- }
|