From dfe46245d2bbf6ec70ee2a58b6ef6b94fd20f3e9 Mon Sep 17 00:00:00 2001 From: Jonathan Poelen Date: Sun, 3 Apr 2016 20:07:37 +0200 Subject: [PATCH] optimized map::at * optimized map::at * fixes lookup/map::at with C-style array type * [msvc] fixes lookup * [msvc] fixes lookup --- brigand/sequences/map.hpp | 135 ++++++-------------------------------- test/map_test.cpp | 2 + 2 files changed, 23 insertions(+), 114 deletions(-) diff --git a/brigand/sequences/map.hpp b/brigand/sequences/map.hpp index a44a07c..0d1608c 100644 --- a/brigand/sequences/map.hpp +++ b/brigand/sequences/map.hpp @@ -13,8 +13,16 @@ namespace brigand { +namespace lazy +{ + template + struct lookup + : decltype(M::at(type_{})) + {}; +} + template - using lookup = decltype(M::at(type_{})); + using lookup = typename lazy::lookup::type; namespace detail { @@ -47,128 +55,27 @@ namespace detail struct map_impl<> { template - static no_such_type_ at(U); + static type_ at(U); template static map_impl insert(type_); }; - // fastlane for constant amortized time - template - struct map_impl : map_inserter - { - static typename T0::second_type at(type_); - - template - static no_such_type_ at(U); - }; - - template - struct map_impl : map_inserter - { - static typename T0::second_type at(type_); - static typename T1::second_type at(type_); - - template - static no_such_type_ at(U); - }; - - template - struct map_impl : map_inserter - { - static typename T0::second_type at(type_); - static typename T1::second_type at(type_); - static typename T2::second_type at(type_); - - template - static no_such_type_ at(U); - }; - - template - struct map_impl : map_inserter - { - static typename T0::second_type at(type_); - static typename T1::second_type at(type_); - static typename T2::second_type at(type_); - static typename T3::second_type at(type_); - - template - static no_such_type_ at(U); - }; - - template - struct map_impl : map_inserter - { - static typename T0::second_type at(type_); - static typename T1::second_type at(type_); - static typename T2::second_type at(type_); - static typename T3::second_type at(type_); - static typename T4::second_type at(type_); - - template - static no_such_type_ at(U); - }; - - template - struct map_impl : map_inserter - { - static typename T0::second_type at(type_); - static typename T1::second_type at(type_); - static typename T2::second_type at(type_); - static typename T3::second_type at(type_); - static typename T4::second_type at(type_); - static typename T5::second_type at(type_); - - template - static no_such_type_ at(U); - }; - - template - struct map_impl : map_inserter + template + struct map_impl : map_inserter { - static typename T0::second_type at(type_); - static typename T1::second_type at(type_); - static typename T2::second_type at(type_); - static typename T3::second_type at(type_); - static typename T4::second_type at(type_); - static typename T5::second_type at(type_); - static typename T6::second_type at(type_); + private: + struct Pack : pair... {}; - template - static no_such_type_ at(U); - }; + template + static type_ at_impl(pair*); - template - struct map_impl : map_inserter - { - static typename T0::second_type at(type_); - static typename T1::second_type at(type_); - static typename T2::second_type at(type_); - static typename T3::second_type at(type_); - static typename T4::second_type at(type_); - static typename T5::second_type at(type_); - static typename T6::second_type at(type_); - static typename T7::second_type at(type_); + public: + template + static decltype(at_impl(static_cast(nullptr))) at(type_); - template - static no_such_type_ at(U); - }; - - - template - struct map_impl : map_inserter - { - static typename T0::second_type at(type_); - static typename T1::second_type at(type_); - static typename T2::second_type at(type_); - static typename T3::second_type at(type_); - static typename T4::second_type at(type_); - static typename T5::second_type at(type_); - static typename T6::second_type at(type_); - static typename T7::second_type at(type_); - - template - static decltype(map_impl::at(U{})) at(U); + template + static type_ at(K); }; // if you have a "class already a base" error message, it means you have defined a map with the same key present more diff --git a/test/map_test.cpp b/test/map_test.cpp index bdcbac5..fb12119 100644 --- a/test/map_test.cpp +++ b/test/map_test.cpp @@ -10,6 +10,8 @@ static_assert(brigand::detail::has_at_method>::value, "at not det // empty maps are allowed static_assert(brigand::size>::value == 0, "empty map isn't empty"); static_assert(std::is_same, int>, brigand::no_such_type_>::value, "should find no such type in empty map"); +static_assert(std::is_same>, int>, int[1]>::value, "should be int[1]"); +static_assert(std::is_same>, int[1]>, int>::value, "should be int"); using map_test = brigand::map, brigand::pair>;