[libcxx] r274418 - Rewrite std::get<Type>(...) helper using constexpr functions.

Eric Fiselier via cfe-commits cfe-commits at lists.llvm.org
Fri Jul 1 20:18:31 PDT 2016


Author: ericwf
Date: Fri Jul  1 22:18:30 2016
New Revision: 274418

URL: http://llvm.org/viewvc/llvm-project?rev=274418&view=rev
Log:
Rewrite std::get<Type>(...) helper using constexpr functions.

Added:
    libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type.fail.cpp
Removed:
    libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type1.fail.cpp
    libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type2.fail.cpp
    libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type3.fail.cpp
    libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type4.fail.cpp
Modified:
    libcxx/trunk/include/tuple

Modified: libcxx/trunk/include/tuple
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/tuple?rev=274418&r1=274417&r2=274418&view=diff
==============================================================================
--- libcxx/trunk/include/tuple (original)
+++ libcxx/trunk/include/tuple Fri Jul  1 22:18:30 2016
@@ -986,39 +986,39 @@ get(const tuple<_Tp...>&& __t) _NOEXCEPT
 }
 
 #if _LIBCPP_STD_VER > 11
-// get by type
-template <typename _T1, size_t _Idx, typename... _Args>
-struct __find_exactly_one_t_helper;
-
-// -- find exactly one
-template <typename _T1, size_t _Idx, typename... _Args>
-struct __find_exactly_one_t_checker {
-    static constexpr size_t value = _Idx;
-//  Check the rest of the list to make sure there's only one
-    static_assert ( __find_exactly_one_t_helper<_T1, 0, _Args...>::value == -1, "type can only occur once in type list" );
-    };
-
-
-template <typename _T1, size_t _Idx>
-struct __find_exactly_one_t_helper <_T1, _Idx> {
-    static constexpr size_t value = -1;
-    };
-
-template <typename _T1, size_t _Idx, typename _Head, typename... _Args>
-struct __find_exactly_one_t_helper <_T1, _Idx, _Head, _Args...> {
-    static constexpr size_t value =
-        std::conditional<
-            std::is_same<_T1, _Head>::value,
-            __find_exactly_one_t_checker<_T1, _Idx,   _Args...>,
-            __find_exactly_one_t_helper <_T1, _Idx+1, _Args...>
-        >::type::value;
-    };
+
+namespace __find_detail {
+
+static constexpr size_t __not_found = -1;
+static constexpr size_t __ambiguous = __not_found - 1;
+
+inline _LIBCPP_INLINE_VISIBILITY
+constexpr size_t __find_idx_return(size_t __curr_i, size_t __res, bool __matches) {
+    return !__matches ? __res :
+        (__res == __not_found ? __curr_i : __ambiguous);
+}
+
+template <size_t _Nx>
+inline _LIBCPP_INLINE_VISIBILITY
+constexpr size_t __find_idx(size_t __i, const bool (&__matches)[_Nx]) {
+  return __i == _Nx ? __not_found :
+      __find_idx_return(__i, __find_idx(__i + 1, __matches), __matches[__i]);
+}
+
+template <class _T1, class ..._Args>
+struct __find_exactly_one_checked {
+  static constexpr bool __matches[] = {is_same<_T1, _Args>::value...};
+    static constexpr size_t value = __find_detail::__find_idx(0, __matches);
+    static_assert (value != __not_found, "type not found in type list" );
+    static_assert(value != __ambiguous,"type occurs more than once in type list");
+};
+
+} // namespace __find_detail;
 
 template <typename _T1, typename... _Args>
-struct __find_exactly_one_t {
-    static constexpr size_t value = __find_exactly_one_t_helper<_T1, 0, _Args...>::value;
-    static_assert ( value != -1, "type not found in type list" );
-    };
+struct __find_exactly_one_t
+    : public __find_detail::__find_exactly_one_checked<_T1, _Args...> {
+};
 
 template <class _T1, class... _Args>
 inline _LIBCPP_INLINE_VISIBILITY

Added: libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type.fail.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type.fail.cpp?rev=274418&view=auto
==============================================================================
--- libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type.fail.cpp (added)
+++ libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type.fail.cpp Fri Jul  1 22:18:30 2016
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11
+
+#include <tuple>
+#include <string>
+
+struct UserType {};
+
+void test_bad_index() {
+    std::tuple<long, long, char, std::string, char, UserType, char> t1;
+    (void)std::get<int>(t1); // expected-error at tuple:* {{type not found}}
+    (void)std::get<long>(t1); // expected-note {{requested here}}
+    (void)std::get<char>(t1); // expected-note {{requested here}}
+        // expected-error at tuple:* 2 {{type occurs more than once}}
+}
+
+void test_bad_return_type() {
+    typedef std::unique_ptr<int> upint;
+    std::tuple<upint> t;
+    upint p = std::get<upint>(t); // expected-error{{deleted copy constructor}}
+}
+
+int main()
+{
+    test_bad_index();
+    test_bad_return_type();
+}

Removed: libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type1.fail.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type1.fail.cpp?rev=274417&view=auto
==============================================================================
--- libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type1.fail.cpp (original)
+++ libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type1.fail.cpp (removed)
@@ -1,23 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is dual licensed under the MIT and the University of Illinois Open
-// Source Licenses. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: c++98, c++03, c++11
-
-#include <tuple>
-#include <string>
-#include <complex>
-
-#include <cassert>
-
-int main()
-{
-    typedef std::complex<float> cf;
-    auto t1 = std::make_tuple<int, std::string> ( 42, "Hi" );
-    assert (( std::get<cf>(t1) == cf {1,2} )); // no such type
-}

Removed: libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type2.fail.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type2.fail.cpp?rev=274417&view=auto
==============================================================================
--- libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type2.fail.cpp (original)
+++ libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type2.fail.cpp (removed)
@@ -1,23 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is dual licensed under the MIT and the University of Illinois Open
-// Source Licenses. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: c++98, c++03, c++11
-
-#include <tuple>
-#include <string>
-#include <complex>
-
-#include <cassert>
-
-int main()
-{
-    typedef std::complex<float> cf;
-    auto t1 = std::make_tuple<int, int, std::string, cf> ( 42, 21, "Hi", { 1,2 } );
-    assert ( std::get<int>(t1) == 42 ); // two ints here
-}

Removed: libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type3.fail.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type3.fail.cpp?rev=274417&view=auto
==============================================================================
--- libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type3.fail.cpp (original)
+++ libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type3.fail.cpp (removed)
@@ -1,23 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is dual licensed under the MIT and the University of Illinois Open
-// Source Licenses. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: c++98, c++03, c++11
-
-#include <tuple>
-#include <string>
-#include <complex>
-
-#include <cassert>
-
-int main()
-{
-    typedef std::complex<float> cf;
-    auto t1 = std::make_tuple<double, int, std::string, cf, int> ( 42, 21, "Hi", { 1,2 } );
-    assert ( std::get<int>(t1) == 42 ); // two ints here (one at the end)
-}

Removed: libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type4.fail.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type4.fail.cpp?rev=274417&view=auto
==============================================================================
--- libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type4.fail.cpp (original)
+++ libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type4.fail.cpp (removed)
@@ -1,23 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is dual licensed under the MIT and the University of Illinois Open
-// Source Licenses. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: c++98, c++03, c++11
-
-#include <tuple>
-#include <string>
-#include <memory>
-
-#include <cassert>
-
-int main()
-{
-    typedef std::unique_ptr<int> upint;
-    std::tuple<upint> t(upint(new int(4)));
-    upint p = std::get<upint>(t);
-}




More information about the cfe-commits mailing list