diff --git a/brigand/sequences/map.hpp b/brigand/sequences/map.hpp index c144429..a44a07c 100644 --- a/brigand/sequences/map.hpp +++ b/brigand/sequences/map.hpp @@ -12,21 +12,50 @@ namespace brigand { + + template + using lookup = decltype(M::at(type_{})); + namespace detail { template struct map_impl; + template + struct map_inserter_impl + { + using index_type = typename K::first_type; + using map_type = map_impl; + using find_result = lookup; + using type = decltype(map_type::template insert_impl(find_result{})); + }; + + template + struct map_inserter + { + template + static map_impl insert_impl(U); + + template + static map_impl insert_impl(no_such_type_); + + template + static typename map_inserter_impl::type insert(type_); + }; + template <> struct map_impl<> { template static no_such_type_ at(U); + + template + static map_impl insert(type_); }; // fastlane for constant amortized time template - struct map_impl + struct map_impl : map_inserter { static typename T0::second_type at(type_); @@ -35,7 +64,7 @@ namespace detail }; template - struct map_impl + struct map_impl : map_inserter { static typename T0::second_type at(type_); static typename T1::second_type at(type_); @@ -45,7 +74,7 @@ namespace detail }; template - struct map_impl + struct map_impl : map_inserter { static typename T0::second_type at(type_); static typename T1::second_type at(type_); @@ -56,7 +85,7 @@ namespace detail }; template - struct map_impl + struct map_impl : map_inserter { static typename T0::second_type at(type_); static typename T1::second_type at(type_); @@ -68,7 +97,7 @@ namespace detail }; template - struct map_impl + struct map_impl : map_inserter { static typename T0::second_type at(type_); static typename T1::second_type at(type_); @@ -81,7 +110,7 @@ namespace detail }; template - struct map_impl + struct map_impl : map_inserter { static typename T0::second_type at(type_); static typename T1::second_type at(type_); @@ -95,7 +124,7 @@ namespace detail }; template - struct map_impl + struct map_impl : map_inserter { static typename T0::second_type at(type_); static typename T1::second_type at(type_); @@ -110,7 +139,7 @@ namespace detail }; template - struct map_impl + struct map_impl : map_inserter { static typename T0::second_type at(type_); static typename T1::second_type at(type_); @@ -127,7 +156,7 @@ namespace detail template - struct map_impl + struct map_impl : map_inserter { static typename T0::second_type at(type_); static typename T1::second_type at(type_); @@ -151,7 +180,4 @@ namespace detail } template using map = typename detail::make_map::type; - - template - using lookup = decltype(M::at(type_{})); } diff --git a/test/map_test.cpp b/test/map_test.cpp index e61eb61..e52d972 100644 --- a/test/map_test.cpp +++ b/test/map_test.cpp @@ -2,6 +2,7 @@ #include #include #include +#include static_assert(brigand::detail::has_at_method>::value, "at not detected!"); @@ -49,3 +50,69 @@ static_assert(std::is_same, type_seven>::value, static_assert(std::is_same, type_eight>::value, "not found in big map!"); static_assert(std::is_same, float****>::value, "not found in big map!"); static_assert(std::is_same, brigand::no_such_type_>::value, "found in big map!"); + +// test insertions all the way up to the fast lanes + +using pair_one = brigand::pair; +using pair_two = brigand::pair; +using pair_three = brigand::pair; +using pair_four = brigand::pair; +using pair_five = brigand::pair; +using pair_six = brigand::pair; +using pair_seven = brigand::pair; +using pair_eight = brigand::pair; +using pair_nine = brigand::pair; +using pair_ten = brigand::pair; + +using map_of_one = brigand::map; +static_assert(std::is_same, pair_one>, map_of_one>::value, "insertion failed"); +static_assert(std::is_same, map_of_one>::value, "insertion failed"); + +using map_of_two = brigand::map; +static_assert(std::is_same, map_of_two>::value, "insertion failed"); +static_assert(std::is_same, map_of_two>::value, "insertion failed"); + +using map_of_three = brigand::map; +static_assert(std::is_same, map_of_three>::value, "insertion failed"); +static_assert(std::is_same, map_of_three>::value, "insertion failed"); + +using map_of_four = brigand::map; +static_assert(std::is_same, map_of_four>::value, "insertion failed"); +static_assert(std::is_same, map_of_four>::value, "insertion failed"); + +using map_of_five = brigand::map; +static_assert(std::is_same, map_of_five>::value, "insertion failed"); +static_assert(std::is_same, map_of_five>::value, "insertion failed"); + +using map_of_six = brigand::map; +static_assert(std::is_same, map_of_six>::value, "insertion failed"); +static_assert(std::is_same, map_of_six>::value, "insertion failed"); + +using map_of_seven = brigand::map; +static_assert(std::is_same, map_of_seven>::value, "insertion failed"); +static_assert(std::is_same, map_of_seven>::value, "insertion failed"); + +using map_of_eight = brigand::map; +static_assert(std::is_same, map_of_eight>::value, "insertion failed"); +static_assert(std::is_same, map_of_eight>::value, "insertion failed"); + +using map_of_nine = brigand::map; +static_assert(std::is_same, map_of_nine>::value, "insertion failed"); +static_assert(std::is_same, map_of_nine>::value, "insertion failed"); + +using map_of_ten = brigand::map; +static_assert(std::is_same, map_of_ten>::value, "insertion failed"); +static_assert(std::is_same, map_of_ten>::value, "insertion failed"); + +// try exhaustive on big map, we don't do a brigand::fold because we want to test map and insert only we don't want a potential problem in +// fold to interfere with this test +static_assert(std::is_same, big_map>::value, "insertion failed"); +static_assert(std::is_same, big_map>::value, "insertion failed"); +static_assert(std::is_same, big_map>::value, "insertion failed"); +static_assert(std::is_same, big_map>::value, "insertion failed"); +static_assert(std::is_same, big_map>::value, "insertion failed"); +static_assert(std::is_same, big_map>::value, "insertion failed"); +static_assert(std::is_same, big_map>::value, "insertion failed"); +static_assert(std::is_same, big_map>::value, "insertion failed"); +static_assert(std::is_same, big_map>::value, "insertion failed"); +static_assert(std::is_same, big_map>::value, "insertion failed");