Rewrite std::get<Type>(...) helper using constexpr functions.
git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@274418 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -986,39 +986,39 @@ get(const tuple<_Tp...>&& __t) _NOEXCEPT
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if _LIBCPP_STD_VER > 11
|
#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
|
namespace __find_detail {
|
||||||
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" );
|
|
||||||
};
|
|
||||||
|
|
||||||
|
static constexpr size_t __not_found = -1;
|
||||||
|
static constexpr size_t __ambiguous = __not_found - 1;
|
||||||
|
|
||||||
template <typename _T1, size_t _Idx>
|
inline _LIBCPP_INLINE_VISIBILITY
|
||||||
struct __find_exactly_one_t_helper <_T1, _Idx> {
|
constexpr size_t __find_idx_return(size_t __curr_i, size_t __res, bool __matches) {
|
||||||
static constexpr size_t value = -1;
|
return !__matches ? __res :
|
||||||
};
|
(__res == __not_found ? __curr_i : __ambiguous);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename _T1, size_t _Idx, typename _Head, typename... _Args>
|
template <size_t _Nx>
|
||||||
struct __find_exactly_one_t_helper <_T1, _Idx, _Head, _Args...> {
|
inline _LIBCPP_INLINE_VISIBILITY
|
||||||
static constexpr size_t value =
|
constexpr size_t __find_idx(size_t __i, const bool (&__matches)[_Nx]) {
|
||||||
std::conditional<
|
return __i == _Nx ? __not_found :
|
||||||
std::is_same<_T1, _Head>::value,
|
__find_idx_return(__i, __find_idx(__i + 1, __matches), __matches[__i]);
|
||||||
__find_exactly_one_t_checker<_T1, _Idx, _Args...>,
|
}
|
||||||
__find_exactly_one_t_helper <_T1, _Idx+1, _Args...>
|
|
||||||
>::type::value;
|
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>
|
template <typename _T1, typename... _Args>
|
||||||
struct __find_exactly_one_t {
|
struct __find_exactly_one_t
|
||||||
static constexpr size_t value = __find_exactly_one_t_helper<_T1, 0, _Args...>::value;
|
: public __find_detail::__find_exactly_one_checked<_T1, _Args...> {
|
||||||
static_assert ( value != -1, "type not found in type list" );
|
};
|
||||||
};
|
|
||||||
|
|
||||||
template <class _T1, class... _Args>
|
template <class _T1, class... _Args>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
inline _LIBCPP_INLINE_VISIBILITY
|
||||||
|
|||||||
@@ -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@tuple:* {{type not found}}
|
||||||
|
(void)std::get<long>(t1); // expected-note {{requested here}}
|
||||||
|
(void)std::get<char>(t1); // expected-note {{requested here}}
|
||||||
|
// expected-error@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();
|
||||||
|
}
|
||||||
@@ -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
|
|
||||||
}
|
|
||||||
@@ -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
|
|
||||||
}
|
|
||||||
@@ -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)
|
|
||||||
}
|
|
||||||
@@ -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);
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user