diff options
Diffstat (limited to 'src/boost/libs/hana/test/concept/struct')
15 files changed, 771 insertions, 0 deletions
diff --git a/src/boost/libs/hana/test/concept/struct/any_of.cpp b/src/boost/libs/hana/test/concept/struct/any_of.cpp new file mode 100644 index 00000000..8dd9082a --- /dev/null +++ b/src/boost/libs/hana/test/concept/struct/any_of.cpp @@ -0,0 +1,46 @@ +// 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/any_of.hpp> +#include <boost/hana/assert.hpp> +#include <boost/hana/concept/struct.hpp> +#include <boost/hana/equal.hpp> +#include <boost/hana/integral_constant.hpp> +#include <boost/hana/not.hpp> + +#include "minimal_struct.hpp" +namespace hana = boost::hana; + + +template <int i = 0> +struct undefined { }; + +int main() { + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::any_of( + obj(), + undefined<>{} + ))); + + BOOST_HANA_CONSTANT_CHECK(hana::any_of( + obj(undefined<0>{}), + hana::equal.to(hana::int_c<0>) + )); + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::any_of( + obj(undefined<0>{}), + hana::equal.to(hana::int_c<1>) + ))); + + BOOST_HANA_CONSTANT_CHECK(hana::any_of( + obj(undefined<0>{}, undefined<1>{}), + hana::equal.to(hana::int_c<0>) + )); + BOOST_HANA_CONSTANT_CHECK(hana::any_of( + obj(undefined<0>{}, undefined<1>{}), + hana::equal.to(hana::int_c<1>) + )); + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::any_of( + obj(undefined<0>{}, undefined<1>{}), + hana::equal.to(hana::int_c<2>) + ))); +} diff --git a/src/boost/libs/hana/test/concept/struct/at_key.cpp b/src/boost/libs/hana/test/concept/struct/at_key.cpp new file mode 100644 index 00000000..2a9d757b --- /dev/null +++ b/src/boost/libs/hana/test/concept/struct/at_key.cpp @@ -0,0 +1,55 @@ +// 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/assert.hpp> +#include <boost/hana/at_key.hpp> +#include <boost/hana/define_struct.hpp> +#include <boost/hana/string.hpp> + +#include <string> +namespace hana = boost::hana; + + +struct Person { + BOOST_HANA_DEFINE_STRUCT(Person, + (std::string, name), + (std::string, last_name), + (int, age) + ); +}; + +int main() { + // non-const ref + { + Person john{"John", "Doe", 30}; + std::string& name = hana::at_key(john, BOOST_HANA_STRING("name")); + std::string& last_name = hana::at_key(john, BOOST_HANA_STRING("last_name")); + int& age = hana::at_key(john, BOOST_HANA_STRING("age")); + + name = "Bob"; + last_name = "Foo"; + age = 99; + + BOOST_HANA_RUNTIME_CHECK(john.name == "Bob"); + BOOST_HANA_RUNTIME_CHECK(john.last_name == "Foo"); + BOOST_HANA_RUNTIME_CHECK(john.age == 99); + } + + // const ref + { + Person john{"John", "Doe", 30}; + Person const& const_john = john; + std::string const& name = hana::at_key(const_john, BOOST_HANA_STRING("name")); + std::string const& last_name = hana::at_key(const_john, BOOST_HANA_STRING("last_name")); + int const& age = hana::at_key(const_john, BOOST_HANA_STRING("age")); + + john.name = "Bob"; + john.last_name = "Foo"; + john.age = 99; + + BOOST_HANA_RUNTIME_CHECK(name == "Bob"); + BOOST_HANA_RUNTIME_CHECK(last_name == "Foo"); + BOOST_HANA_RUNTIME_CHECK(age == 99); + } +} diff --git a/src/boost/libs/hana/test/concept/struct/equal.cpp b/src/boost/libs/hana/test/concept/struct/equal.cpp new file mode 100644 index 00000000..3bd91689 --- /dev/null +++ b/src/boost/libs/hana/test/concept/struct/equal.cpp @@ -0,0 +1,47 @@ +// 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/assert.hpp> +#include <boost/hana/concept/struct.hpp> +#include <boost/hana/equal.hpp> +#include <boost/hana/not.hpp> + +#include "minimal_struct.hpp" +#include <laws/base.hpp> +namespace hana = boost::hana; +using hana::test::ct_eq; + + +int main() { + BOOST_HANA_CONSTANT_CHECK(hana::equal( + obj(), + obj() + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + obj(ct_eq<0>{}), + obj(ct_eq<0>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal( + obj(ct_eq<0>{}), + obj(ct_eq<1>{}) + ))); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + obj(ct_eq<0>{}, ct_eq<1>{}), + obj(ct_eq<0>{}, ct_eq<1>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal( + obj(ct_eq<1>{}, ct_eq<0>{}), + obj(ct_eq<0>{}, ct_eq<1>{}) + ))); + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal( + obj(ct_eq<0>{}, ct_eq<99>{}), + obj(ct_eq<0>{}, ct_eq<1>{}) + ))); + BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal( + obj(ct_eq<99>{}, ct_eq<1>{}), + obj(ct_eq<0>{}, ct_eq<1>{}) + ))); +} diff --git a/src/boost/libs/hana/test/concept/struct/find_if.cpp b/src/boost/libs/hana/test/concept/struct/find_if.cpp new file mode 100644 index 00000000..3e249239 --- /dev/null +++ b/src/boost/libs/hana/test/concept/struct/find_if.cpp @@ -0,0 +1,48 @@ +// 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/assert.hpp> +#include <boost/hana/concept/struct.hpp> +#include <boost/hana/equal.hpp> +#include <boost/hana/find_if.hpp> +#include <boost/hana/integral_constant.hpp> +#include <boost/hana/optional.hpp> + +#include "minimal_struct.hpp" +#include <laws/base.hpp> +namespace hana = boost::hana; +using hana::test::ct_eq; + + +template <int i = 0> +struct undefined { }; + +int main() { + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::find_if(obj(), undefined<>{}), + hana::nothing + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::find_if(obj(ct_eq<0>{}), hana::equal.to(hana::int_c<0>)), + hana::just(ct_eq<0>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::find_if(obj(undefined<1>{}), hana::equal.to(hana::int_c<1>)), + hana::nothing + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::find_if(obj(ct_eq<0>{}, ct_eq<1>{}), hana::equal.to(hana::int_c<0>)), + hana::just(ct_eq<0>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::find_if(obj(ct_eq<0>{}, ct_eq<1>{}), hana::equal.to(hana::int_c<1>)), + hana::just(ct_eq<1>{}) + )); + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::find_if(obj(undefined<0>{}, undefined<1>{}), hana::equal.to(hana::int_c<2>)), + hana::nothing + )); +} diff --git a/src/boost/libs/hana/test/concept/struct/fold_left.cpp b/src/boost/libs/hana/test/concept/struct/fold_left.cpp new file mode 100644 index 00000000..f7b63814 --- /dev/null +++ b/src/boost/libs/hana/test/concept/struct/fold_left.cpp @@ -0,0 +1,59 @@ +// 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/assert.hpp> +#include <boost/hana/concept/struct.hpp> +#include <boost/hana/equal.hpp> +#include <boost/hana/fold_left.hpp> +#include <boost/hana/integral_constant.hpp> + +#include "minimal_struct.hpp" +#include <laws/base.hpp> +#include <support/minimal_product.hpp> +namespace hana = boost::hana; +using hana::test::ct_eq; + + +template <int i = 0> +struct undefined { }; + +struct MoveOnly { + MoveOnly() = default; + MoveOnly(MoveOnly&&) = default; + MoveOnly(MoveOnly const&) = delete; + MoveOnly& operator=(MoveOnly&&) = default; + MoveOnly& operator=(MoveOnly const&) = delete; +}; + +int main() { + constexpr auto pair = ::minimal_product; + ct_eq<999> s{}; + hana::test::_injection<0> f{}; + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::fold_left(obj(), s, undefined<>{}), + s + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::fold_left(obj(ct_eq<0>{}), s, f), + f(s, pair(hana::int_c<0>, ct_eq<0>{})) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::fold_left(obj(ct_eq<0>{}, ct_eq<1>{}), s, f), + f(f(s, pair(hana::int_c<0>, ct_eq<0>{})), pair(hana::int_c<1>, ct_eq<1>{})) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::fold_left(obj(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), s, f), + f(f(f(s, pair(hana::int_c<0>, ct_eq<0>{})), + pair(hana::int_c<1>, ct_eq<1>{})), + pair(hana::int_c<2>, ct_eq<2>{})) + )); + + // fold_left with move-only members + hana::fold_left(obj(MoveOnly{}), 0, [](int, auto) { return 0; }); + hana::fold_left(obj(MoveOnly{}, MoveOnly{}), 0, [](int, auto) { return 0; }); +} diff --git a/src/boost/libs/hana/test/concept/struct/fold_right.cpp b/src/boost/libs/hana/test/concept/struct/fold_right.cpp new file mode 100644 index 00000000..3db67def --- /dev/null +++ b/src/boost/libs/hana/test/concept/struct/fold_right.cpp @@ -0,0 +1,59 @@ +// 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/assert.hpp> +#include <boost/hana/concept/struct.hpp> +#include <boost/hana/equal.hpp> +#include <boost/hana/fold_right.hpp> +#include <boost/hana/integral_constant.hpp> + +#include "minimal_struct.hpp" +#include <laws/base.hpp> +#include <support/minimal_product.hpp> +namespace hana = boost::hana; +using hana::test::ct_eq; + + +template <int i = 0> +struct undefined { }; + +struct MoveOnly { + MoveOnly() = default; + MoveOnly(MoveOnly&&) = default; + MoveOnly(MoveOnly const&) = delete; + MoveOnly& operator=(MoveOnly&&) = default; + MoveOnly& operator=(MoveOnly const&) = delete; +}; + +int main() { + constexpr auto pair = ::minimal_product; + ct_eq<999> s{}; + hana::test::_injection<0> f{}; + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::fold_right(obj(), s, undefined<>{}), + s + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::fold_right(obj(ct_eq<0>{}), s, f), + f(pair(hana::int_c<0>, ct_eq<0>{}), s) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::fold_right(obj(ct_eq<0>{}, ct_eq<1>{}), s, f), + f(pair(hana::int_c<0>, ct_eq<0>{}), f(pair(hana::int_c<1>, ct_eq<1>{}), s)) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::fold_right(obj(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), s, f), + f(pair(hana::int_c<0>, ct_eq<0>{}), + f(pair(hana::int_c<1>, ct_eq<1>{}), + f(pair(hana::int_c<2>, ct_eq<2>{}), s))) + )); + + // fold_right with move-only members + hana::fold_right(obj(MoveOnly{}), 0, [](auto, int) { return 0; }); + hana::fold_right(obj(MoveOnly{}, MoveOnly{}), 0, [](auto, int) { return 0; }); +} diff --git a/src/boost/libs/hana/test/concept/struct/keys.cpp b/src/boost/libs/hana/test/concept/struct/keys.cpp new file mode 100644 index 00000000..c07de9e1 --- /dev/null +++ b/src/boost/libs/hana/test/concept/struct/keys.cpp @@ -0,0 +1,46 @@ +// 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/assert.hpp> +#include <boost/hana/concept/struct.hpp> +#include <boost/hana/equal.hpp> +#include <boost/hana/integral_constant.hpp> +#include <boost/hana/keys.hpp> + +#include "minimal_struct.hpp" +#include <laws/base.hpp> +#include <support/seq.hpp> +namespace hana = boost::hana; +using hana::test::ct_eq; + + +template <int i = 0> +struct undefined { }; + +int main() { + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::keys(obj()), + ::seq() + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::keys(obj(undefined<0>{})), + ::seq(hana::int_c<0>) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::keys(obj(undefined<0>{}, undefined<1>{})), + ::seq(hana::int_c<0>, hana::int_c<1>) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::keys(obj(undefined<0>{}, undefined<1>{}, undefined<2>{})), + ::seq(hana::int_c<0>, hana::int_c<1>, hana::int_c<2>) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::keys(obj(undefined<0>{}, undefined<1>{}, undefined<2>{}, undefined<3>{})), + ::seq(hana::int_c<0>, hana::int_c<1>, hana::int_c<2>, hana::int_c<3>) + )); +} diff --git a/src/boost/libs/hana/test/concept/struct/laws.cpp b/src/boost/libs/hana/test/concept/struct/laws.cpp new file mode 100644 index 00000000..b10955db --- /dev/null +++ b/src/boost/libs/hana/test/concept/struct/laws.cpp @@ -0,0 +1,43 @@ +// 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/concept/struct.hpp> +#include <boost/hana/integral_constant.hpp> +#include <boost/hana/tuple.hpp> + +#include "minimal_struct.hpp" +#include <laws/base.hpp> +#include <laws/comparable.hpp> +#include <laws/foldable.hpp> +#include <laws/searchable.hpp> +namespace hana = boost::hana; +using hana::test::ct_eq; + + +int main() { + auto eq0 = hana::make_tuple(obj()); + auto eq1 = hana::make_tuple( + obj(ct_eq<0>{}), obj(ct_eq<1>{}), obj(ct_eq<2>{}) + ); + auto eq2 = hana::make_tuple( + obj(ct_eq<0>{}, ct_eq<0>{}), + obj(ct_eq<0>{}, ct_eq<1>{}), + obj(ct_eq<1>{}, ct_eq<0>{}), + obj(ct_eq<1>{}, ct_eq<1>{}), + obj(ct_eq<0>{}, ct_eq<2>{}), + obj(ct_eq<2>{}, ct_eq<3>{}) + ); + + hana::test::TestComparable<minimal_struct_tag<0>>{eq0}; + hana::test::TestComparable<minimal_struct_tag<1>>{eq1}; + hana::test::TestComparable<minimal_struct_tag<2>>{eq2}; + + hana::test::TestFoldable<minimal_struct_tag<0>>{eq0}; + hana::test::TestFoldable<minimal_struct_tag<1>>{eq1}; + hana::test::TestFoldable<minimal_struct_tag<2>>{eq2}; + + hana::test::TestSearchable<minimal_struct_tag<0>>{eq0, hana::make_tuple()}; + hana::test::TestSearchable<minimal_struct_tag<1>>{eq1, hana::make_tuple(hana::int_c<0>)}; + hana::test::TestSearchable<minimal_struct_tag<2>>{eq2, hana::make_tuple(hana::int_c<0>, hana::int_c<1>)}; +} diff --git a/src/boost/libs/hana/test/concept/struct/macro.adapt_adt.cpp b/src/boost/libs/hana/test/concept/struct/macro.adapt_adt.cpp new file mode 100644 index 00000000..dc759b42 --- /dev/null +++ b/src/boost/libs/hana/test/concept/struct/macro.adapt_adt.cpp @@ -0,0 +1,61 @@ +// 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/adapt_adt.hpp> +#include <boost/hana/assert.hpp> +#include <boost/hana/concept/struct.hpp> +#include <boost/hana/contains.hpp> +#include <boost/hana/string.hpp> + +#include <laws/base.hpp> +namespace hana = boost::hana; +using hana::test::ct_eq; + + +namespace ns { + struct Data0 { }; + struct Data1 { + ct_eq<1> get_member1() const { return {}; } + }; + struct Data2 { + ct_eq<1> get_member1() const { return {}; } + ct_eq<2> get_member2() const { return {}; } + }; + struct Data3 { + ct_eq<1> get_member1() const { return {}; } + ct_eq<2> get_member2() const { return {}; } + ct_eq<3> get_member3() const { return {}; } + }; +} + +// Note: We use commas in the lambdas to make sure the macro can handle it. +BOOST_HANA_ADAPT_ADT(ns::Data0); +BOOST_HANA_ADAPT_ADT(ns::Data1, + (member1, [](auto const& d) { return 0, d.get_member1(); }) +); +BOOST_HANA_ADAPT_ADT(ns::Data2, + (member1, [](auto const& d) { return 0, d.get_member1(); }), + (member2, [](auto const& d) { return d.get_member2(); }) +); +BOOST_HANA_ADAPT_ADT(ns::Data3, + (member1, [](auto const& d) { return 0, d.get_member1(); }), + (member2, [](auto const& d) { return d.get_member2(); }), + (member3, [](auto const& d) { return d.get_member3(); }) +); + +static_assert(hana::Struct<ns::Data0>::value, ""); +static_assert(hana::Struct<ns::Data1>::value, ""); +static_assert(hana::Struct<ns::Data2>::value, ""); +static_assert(hana::Struct<ns::Data3>::value, ""); + +int main() { + BOOST_HANA_CONSTANT_CHECK(hana::contains(ns::Data1{}, BOOST_HANA_STRING("member1"))); + + BOOST_HANA_CONSTANT_CHECK(hana::contains(ns::Data2{}, BOOST_HANA_STRING("member1"))); + BOOST_HANA_CONSTANT_CHECK(hana::contains(ns::Data2{}, BOOST_HANA_STRING("member2"))); + + BOOST_HANA_CONSTANT_CHECK(hana::contains(ns::Data3{}, BOOST_HANA_STRING("member1"))); + BOOST_HANA_CONSTANT_CHECK(hana::contains(ns::Data3{}, BOOST_HANA_STRING("member2"))); + BOOST_HANA_CONSTANT_CHECK(hana::contains(ns::Data3{}, BOOST_HANA_STRING("member3"))); +} diff --git a/src/boost/libs/hana/test/concept/struct/macro.adapt_struct.cpp b/src/boost/libs/hana/test/concept/struct/macro.adapt_struct.cpp new file mode 100644 index 00000000..6aec33d5 --- /dev/null +++ b/src/boost/libs/hana/test/concept/struct/macro.adapt_struct.cpp @@ -0,0 +1,58 @@ +// 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/adapt_struct.hpp> +#include <boost/hana/assert.hpp> +#include <boost/hana/concept/struct.hpp> +#include <boost/hana/contains.hpp> +#include <boost/hana/string.hpp> + +#include <laws/base.hpp> +namespace hana = boost::hana; +using hana::test::ct_eq; + + +namespace ns { + struct Data0 { }; + struct Data1 { + ct_eq<1> member1; + }; + struct Data2 { + ct_eq<1> member1; + ct_eq<2> member2; + }; + struct Data3 { + ct_eq<1> member1; + ct_eq<2> member2; + ct_eq<3> member3; + }; + struct MemberArray { + int array[10]; + }; +} + +BOOST_HANA_ADAPT_STRUCT(ns::Data0); +BOOST_HANA_ADAPT_STRUCT(ns::Data1, member1); +BOOST_HANA_ADAPT_STRUCT(ns::Data2, member1, member2); +BOOST_HANA_ADAPT_STRUCT(ns::Data3, member1, member2, member3); +BOOST_HANA_ADAPT_STRUCT(ns::MemberArray, array); + +static_assert(hana::Struct<ns::Data0>::value, ""); +static_assert(hana::Struct<ns::Data1>::value, ""); +static_assert(hana::Struct<ns::Data2>::value, ""); +static_assert(hana::Struct<ns::Data3>::value, ""); +static_assert(hana::Struct<ns::MemberArray>::value, ""); + +int main() { + BOOST_HANA_CONSTANT_CHECK(hana::contains(ns::Data1{}, BOOST_HANA_STRING("member1"))); + + BOOST_HANA_CONSTANT_CHECK(hana::contains(ns::Data2{}, BOOST_HANA_STRING("member1"))); + BOOST_HANA_CONSTANT_CHECK(hana::contains(ns::Data2{}, BOOST_HANA_STRING("member2"))); + + BOOST_HANA_CONSTANT_CHECK(hana::contains(ns::Data3{}, BOOST_HANA_STRING("member1"))); + BOOST_HANA_CONSTANT_CHECK(hana::contains(ns::Data3{}, BOOST_HANA_STRING("member2"))); + BOOST_HANA_CONSTANT_CHECK(hana::contains(ns::Data3{}, BOOST_HANA_STRING("member3"))); + + BOOST_HANA_CONSTANT_CHECK(hana::contains(ns::MemberArray{}, BOOST_HANA_STRING("array"))); +} diff --git a/src/boost/libs/hana/test/concept/struct/macro.define_struct.cpp b/src/boost/libs/hana/test/concept/struct/macro.define_struct.cpp new file mode 100644 index 00000000..29ddbfdd --- /dev/null +++ b/src/boost/libs/hana/test/concept/struct/macro.define_struct.cpp @@ -0,0 +1,57 @@ +// 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/assert.hpp> +#include <boost/hana/concept/struct.hpp> +#include <boost/hana/contains.hpp> +#include <boost/hana/define_struct.hpp> +#include <boost/hana/string.hpp> + +#include <laws/base.hpp> +namespace hana = boost::hana; +using hana::test::ct_eq; + + +// This allows us to make sure we can enter template types +// containing commas in the macro. +template <typename T, typename ...> +using commas = T; + +struct Data0 { + BOOST_HANA_DEFINE_STRUCT(Data0); +}; +struct Data1 { + BOOST_HANA_DEFINE_STRUCT(Data1, + (commas<ct_eq<1>, void>, member1) + ); +}; +struct Data2 { + BOOST_HANA_DEFINE_STRUCT(Data2, + (commas<ct_eq<1>, void, void>, member1), + (ct_eq<2>, member2) + ); +}; +struct Data3 { + BOOST_HANA_DEFINE_STRUCT(Data3, + (ct_eq<1>, member1), + (ct_eq<2>, member2), + (commas<ct_eq<3>, void, void, void>, member3) + ); +}; + +static_assert(hana::Struct<Data0>::value, ""); +static_assert(hana::Struct<Data1>::value, ""); +static_assert(hana::Struct<Data2>::value, ""); +static_assert(hana::Struct<Data3>::value, ""); + +int main() { + BOOST_HANA_CONSTANT_CHECK(hana::contains(Data1{}, BOOST_HANA_STRING("member1"))); + + BOOST_HANA_CONSTANT_CHECK(hana::contains(Data2{}, BOOST_HANA_STRING("member1"))); + BOOST_HANA_CONSTANT_CHECK(hana::contains(Data2{}, BOOST_HANA_STRING("member2"))); + + BOOST_HANA_CONSTANT_CHECK(hana::contains(Data3{}, BOOST_HANA_STRING("member1"))); + BOOST_HANA_CONSTANT_CHECK(hana::contains(Data3{}, BOOST_HANA_STRING("member2"))); + BOOST_HANA_CONSTANT_CHECK(hana::contains(Data3{}, BOOST_HANA_STRING("member3"))); +} diff --git a/src/boost/libs/hana/test/concept/struct/member_function.cpp b/src/boost/libs/hana/test/concept/struct/member_function.cpp new file mode 100644 index 00000000..1e3ab6ec --- /dev/null +++ b/src/boost/libs/hana/test/concept/struct/member_function.cpp @@ -0,0 +1,43 @@ +// 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/assert.hpp> +#include <boost/hana/for_each.hpp> +#include <boost/hana/fuse.hpp> +#include <boost/hana/fwd/accessors.hpp> +#include <boost/hana/pair.hpp> +#include <boost/hana/string.hpp> +#include <boost/hana/tuple.hpp> + +#include <string> +namespace hana = boost::hana; + + +// +// Unit test inspired by http://stackoverflow.com/q/32678647/627587 +// + +struct Foo { + std::string get_name() const { return "louis"; } +}; + +namespace boost { namespace hana { + template <> + struct accessors_impl<Foo> { + static auto apply() { + return hana::make_tuple( + hana::make_pair(BOOST_HANA_STRING("get_name"), [](auto const& foo) { + return foo.get_name(); + }) + ); + } + }; +}} + +int main() { + Foo foo; + hana::for_each(foo, hana::fuse([](auto /*key*/, std::string const& name) { + BOOST_HANA_RUNTIME_CHECK(name == "louis"); + })); +} diff --git a/src/boost/libs/hana/test/concept/struct/members.cpp b/src/boost/libs/hana/test/concept/struct/members.cpp new file mode 100644 index 00000000..1734b519 --- /dev/null +++ b/src/boost/libs/hana/test/concept/struct/members.cpp @@ -0,0 +1,51 @@ +// 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/assert.hpp> +#include <boost/hana/concept/struct.hpp> +#include <boost/hana/equal.hpp> +#include <boost/hana/members.hpp> + +#include "minimal_struct.hpp" +#include <laws/base.hpp> +#include <support/seq.hpp> +namespace hana = boost::hana; +using hana::test::ct_eq; + + +struct MoveOnly { + MoveOnly() = default; + MoveOnly(MoveOnly&&) = default; + MoveOnly(MoveOnly const&) = delete; + MoveOnly& operator=(MoveOnly&&) = default; + MoveOnly& operator=(MoveOnly const&) = delete; +}; + +int main() { + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::members(obj()), + ::seq() + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::members(obj(ct_eq<0>{})), + ::seq(ct_eq<0>{}) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::members(obj(ct_eq<0>{}, ct_eq<1>{})), + ::seq(ct_eq<0>{}, ct_eq<1>{}) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::members(obj(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{})), + ::seq(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}) + )); + + // make sure it works with move only types + auto z1 = hana::members(obj(MoveOnly{})); + auto z2 = hana::members(obj(MoveOnly{}, MoveOnly{})); + (void)z1; + (void)z2; +} diff --git a/src/boost/libs/hana/test/concept/struct/minimal_struct.hpp b/src/boost/libs/hana/test/concept/struct/minimal_struct.hpp new file mode 100644 index 00000000..4eea80df --- /dev/null +++ b/src/boost/libs/hana/test/concept/struct/minimal_struct.hpp @@ -0,0 +1,54 @@ +// 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) + +#ifndef BOOST_HANA_TEST_STRUCT_MINIMAL_STRUCT_HPP +#define BOOST_HANA_TEST_STRUCT_MINIMAL_STRUCT_HPP + +#include <boost/hana/at.hpp> +#include <boost/hana/fwd/accessors.hpp> +#include <boost/hana/pair.hpp> +#include <boost/hana/range.hpp> +#include <boost/hana/tuple.hpp> +#include <boost/hana/unpack.hpp> + + +template <int N> +struct minimal_struct_tag; + +template <typename ...Members> +struct minimal_struct_t { + boost::hana::tuple<Members...> members; + using hana_tag = minimal_struct_tag<sizeof...(Members)>; +}; + +struct obj_t { + template <typename ...Members> + constexpr minimal_struct_t<Members...> operator()(Members ...members) const { + return {{static_cast<Members&&>(members)...}}; + } +}; +constexpr obj_t obj{}; + +namespace boost { namespace hana { + template <int N> + struct accessors_impl<minimal_struct_tag<N>> { + template <typename K> + struct get_member { + template <typename Struct> + constexpr decltype(auto) operator()(Struct&& s) const { + return hana::at_c<K::value>(static_cast<Struct&&>(s).members); + } + }; + + static auto apply() { + return hana::unpack(hana::range_c<int, 0, N>, [](auto ...k) { + return hana::make_tuple( + hana::make_pair(k, get_member<decltype(k)>{})... + ); + }); + } + }; +}} + +#endif // !BOOST_HANA_TEST_STRUCT_MINIMAL_STRUCT_HPP diff --git a/src/boost/libs/hana/test/concept/struct/unpack.cpp b/src/boost/libs/hana/test/concept/struct/unpack.cpp new file mode 100644 index 00000000..30b8982f --- /dev/null +++ b/src/boost/libs/hana/test/concept/struct/unpack.cpp @@ -0,0 +1,44 @@ +// 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/assert.hpp> +#include <boost/hana/concept/struct.hpp> +#include <boost/hana/equal.hpp> +#include <boost/hana/integral_constant.hpp> +#include <boost/hana/unpack.hpp> + +#include "minimal_struct.hpp" +#include <laws/base.hpp> +#include <support/minimal_product.hpp> +namespace hana = boost::hana; +using hana::test::ct_eq; + + +int main() { + constexpr auto pair = ::minimal_product; + hana::test::_injection<0> f{}; + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::unpack(obj(), f), + f() + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::unpack(obj(ct_eq<0>{}), f), + f(pair(hana::int_c<0>, ct_eq<0>{})) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::unpack(obj(ct_eq<0>{}, ct_eq<1>{}), f), + f(pair(hana::int_c<0>, ct_eq<0>{}), + pair(hana::int_c<1>, ct_eq<1>{})) + )); + + BOOST_HANA_CONSTANT_CHECK(hana::equal( + hana::unpack(obj(ct_eq<0>{}, ct_eq<1>{}, ct_eq<2>{}), f), + f(pair(hana::int_c<0>, ct_eq<0>{}), + pair(hana::int_c<1>, ct_eq<1>{}), + pair(hana::int_c<2>, ct_eq<2>{})) + )); +} |