Add super fast _IsSame trait for internal use.

Clang provides __is_same that doesn't produce any instantiations
and just returns a bool. It's a lot faster than using std::is_same

I'll follow up with a patch to actually start using it.

llvm-svn: 364148
This commit is contained in:
Eric Fiselier 2019-06-23 03:58:41 +00:00
parent 6281ccea02
commit de2b633a4a
2 changed files with 77 additions and 11 deletions

View File

@ -542,6 +542,26 @@ template <class _Tp> struct _LIBCPP_TEMPLATE_VIS enable_if<true, _Tp> {typedef _
template <bool _Bp, class _Tp = void> using enable_if_t = typename enable_if<_Bp, _Tp>::type; template <bool _Bp, class _Tp = void> using enable_if_t = typename enable_if<_Bp, _Tp>::type;
#endif #endif
// is_same
template <class _Tp, class _Up> struct _LIBCPP_TEMPLATE_VIS is_same : public false_type {};
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_same<_Tp, _Tp> : public true_type {};
#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
template <class _Tp, class _Up>
_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_same_v
= is_same<_Tp, _Up>::value;
#endif
template <class _Tp, class _Up>
using _IsSame = _BoolConstant<
#ifdef __clang__
__is_same(_Tp, _Up)
#else
_VSTD::is_same<_Tp, _Up>::value
#endif
>;
// addressof // addressof
#ifndef _LIBCPP_HAS_NO_BUILTIN_ADDRESSOF #ifndef _LIBCPP_HAS_NO_BUILTIN_ADDRESSOF
@ -933,17 +953,6 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_class_v
= is_class<_Tp>::value; = is_class<_Tp>::value;
#endif #endif
// is_same
template <class _Tp, class _Up> struct _LIBCPP_TEMPLATE_VIS is_same : public false_type {};
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_same<_Tp, _Tp> : public true_type {};
#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
template <class _Tp, class _Up>
_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_same_v
= is_same<_Tp, _Up>::value;
#endif
// is_function // is_function
namespace __libcpp_is_function_imp namespace __libcpp_is_function_imp

View File

@ -0,0 +1,57 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This is a dummy feature that prevents this test from running by default.
// The table below compares the compile time and object size for each of the
// variants listed in the RUN script.
//
// Impl Compile Time Object Size
// -------------------------------------------
// std::_IsSame: 689.634 ms 356 K
// std::is_same: 8,129.180 ms 560 K
//
// RUN: %cxx %flags %compile_flags -c %s -o %S/orig.o -ggdb -ggnu-pubnames -ftemplate-depth=5000 -ftime-trace -std=c++17
// RUN: %cxx %flags %compile_flags -c %s -o %S/new.o -ggdb -ggnu-pubnames -ftemplate-depth=5000 -ftime-trace -std=c++17 -DTEST_NEW
#include <type_traits>
#include <cassert>
#include "test_macros.h"
#include "template_cost_testing.h"
template <int N> struct Arg { enum { value = 1 }; };
#ifdef TEST_NEW
#define IS_SAME std::_IsSame
#else
#define IS_SAME std::is_same
#endif
#define TEST_CASE_NOP() IS_SAME < Arg< __COUNTER__ >, Arg < __COUNTER__ > >::value,
#define TEST_CASE_TYPE() IS_SAME < Arg< __COUNTER__ >, Arg < __COUNTER__ > >,
int sink(...);
int x = sink(
REPEAT_10000(TEST_CASE_NOP)
REPEAT_10000(TEST_CASE_NOP) 42
);
void Foo( REPEAT_1000(TEST_CASE_TYPE) int) { }
static_assert(__COUNTER__ > 10000, "");
void escape() {
sink(&x);
sink(&Foo);
}