From babaad1cad9d8951ce16cedb81996d0f5f0db28f Mon Sep 17 00:00:00 2001 From: Scott Linder Date: Fri, 30 Apr 2021 17:15:49 +0000 Subject: [PATCH] [ADT] Add STLForwardCompat.h and llvm::disjunction Move some types in STLExtras.h which are named and behave identically to STL types from future standards into a dedicated header. This keeps them organized (they are not "extras" in the same sense as most types in STLExtras.h are) and fixes circular dependencies in future patches. Reviewed By: dblaikie Differential Revision: https://reviews.llvm.org/D100668 --- include/llvm/ADT/STLExtras.h | 32 +++-------------- include/llvm/ADT/STLForwardCompat.h | 49 ++++++++++++++++++++++++++ unittests/ADT/CMakeLists.txt | 1 + unittests/ADT/STLForwardCompatTest.cpp | 45 +++++++++++++++++++++++ 4 files changed, 100 insertions(+), 27 deletions(-) create mode 100644 include/llvm/ADT/STLForwardCompat.h create mode 100644 unittests/ADT/STLForwardCompatTest.cpp diff --git a/include/llvm/ADT/STLExtras.h b/include/llvm/ADT/STLExtras.h index 208156ceaaf..04cdfebc77d 100644 --- a/include/llvm/ADT/STLExtras.h +++ b/include/llvm/ADT/STLExtras.h @@ -17,6 +17,7 @@ #define LLVM_ADT_STLEXTRAS_H #include "llvm/ADT/Optional.h" +#include "llvm/ADT/STLForwardCompat.h" #include "llvm/ADT/iterator.h" #include "llvm/ADT/iterator_range.h" #include "llvm/Config/abi-breaking.h" @@ -60,15 +61,6 @@ using ValueOfRange = typename std::remove_reference //===----------------------------------------------------------------------===// -template -struct negation : std::integral_constant {}; - -template struct conjunction : std::true_type {}; -template struct conjunction : B1 {}; -template -struct conjunction - : std::conditional, B1>::type {}; - template struct make_const_ptr { using type = typename std::add_pointer::type>::type; @@ -1300,27 +1292,13 @@ template <> struct rank<0> {}; /// traits class for checking whether type T is one of any of the given /// types in the variadic list. -template struct is_one_of { - static const bool value = false; -}; - -template -struct is_one_of { - static const bool value = - std::is_same::value || is_one_of::value; -}; +template +using is_one_of = disjunction...>; /// traits class for checking whether type T is a base class for all /// the given types in the variadic list. -template struct are_base_of { - static const bool value = true; -}; - -template -struct are_base_of { - static const bool value = - std::is_base_of::value && are_base_of::value; -}; +template +using are_base_of = conjunction...>; //===----------------------------------------------------------------------===// // Extra additions for arrays diff --git a/include/llvm/ADT/STLForwardCompat.h b/include/llvm/ADT/STLForwardCompat.h new file mode 100644 index 00000000000..40176e72ab1 --- /dev/null +++ b/include/llvm/ADT/STLForwardCompat.h @@ -0,0 +1,49 @@ +//===- STLForwardCompat.h - Library features from future STLs ------C++ -*-===// +// +// 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 file contains library features backported from future STL versions. +// +// These should be replaced with their STL counterparts as the C++ version LLVM +// is compiled with is updated. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ADT_STLFORWARDCOMPAT_H +#define LLVM_ADT_STLFORWARDCOMPAT_H + +#include + +namespace llvm { + +//===----------------------------------------------------------------------===// +// Features from C++17 +//===----------------------------------------------------------------------===// + +template +struct negation // NOLINT(readability-identifier-naming) + : std::integral_constant {}; + +template +struct conjunction // NOLINT(readability-identifier-naming) + : std::true_type {}; +template struct conjunction : B1 {}; +template +struct conjunction + : std::conditional, B1>::type {}; + +template +struct disjunction // NOLINT(readability-identifier-naming) + : std::false_type {}; +template struct disjunction : B1 {}; +template +struct disjunction + : std::conditional>::type {}; + +} // namespace llvm + +#endif // LLVM_ADT_STLFORWARDCOMPAT_H diff --git a/unittests/ADT/CMakeLists.txt b/unittests/ADT/CMakeLists.txt index 51f1b114f5c..e64b1a0c7b3 100644 --- a/unittests/ADT/CMakeLists.txt +++ b/unittests/ADT/CMakeLists.txt @@ -55,6 +55,7 @@ add_llvm_unittest(ADTTests RangeAdapterTest.cpp SCCIteratorTest.cpp STLExtrasTest.cpp + STLForwardCompatTest.cpp ScopeExitTest.cpp SequenceTest.cpp SetVectorTest.cpp diff --git a/unittests/ADT/STLForwardCompatTest.cpp b/unittests/ADT/STLForwardCompatTest.cpp new file mode 100644 index 00000000000..ce7ecba02c7 --- /dev/null +++ b/unittests/ADT/STLForwardCompatTest.cpp @@ -0,0 +1,45 @@ +//===- STLForwardCompatTest.cpp - Unit tests for STLForwardCompat ---------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "llvm/ADT/STLForwardCompat.h" +#include "gtest/gtest.h" + +namespace { + +TEST(STLForwardCompatTest, NegationTest) { + EXPECT_TRUE((llvm::negation::value)); + EXPECT_FALSE((llvm::negation::value)); +} + +struct incomplete_type; + +TEST(STLForwardCompatTest, ConjunctionTest) { + EXPECT_TRUE((llvm::conjunction<>::value)); + EXPECT_FALSE((llvm::conjunction::value)); + EXPECT_TRUE((llvm::conjunction::value)); + EXPECT_FALSE((llvm::conjunction::value)); + EXPECT_FALSE((llvm::conjunction::value)); + EXPECT_FALSE((llvm::conjunction::value)); + EXPECT_TRUE((llvm::conjunction::value)); + EXPECT_TRUE((llvm::conjunction::value)); +} + +TEST(STLForwardCompatTest, DisjunctionTest) { + EXPECT_FALSE((llvm::disjunction<>::value)); + EXPECT_FALSE((llvm::disjunction::value)); + EXPECT_TRUE((llvm::disjunction::value)); + EXPECT_TRUE((llvm::disjunction::value)); + EXPECT_TRUE((llvm::disjunction::value)); + EXPECT_TRUE((llvm::disjunction::value)); + EXPECT_TRUE((llvm::disjunction::value)); + EXPECT_TRUE((llvm::disjunction::value)); +} + +} // namespace