gchatelet updated this revision to Diff 348228.
gchatelet added a comment.

- Rebase


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D102760/new/

https://reviews.llvm.org/D102760

Files:
  clang/include/clang/Basic/Module.h
  llvm/include/llvm/ADT/IterableTraits.h
  llvm/include/llvm/ADT/SmallVector.h
  llvm/tools/llvm-xray/xray-converter.cpp
  llvm/unittests/ADT/CMakeLists.txt
  llvm/unittests/ADT/IterableTraitsTest.cpp
  llvm/unittests/ADT/SmallVectorTest.cpp

Index: llvm/unittests/ADT/SmallVectorTest.cpp
===================================================================
--- llvm/unittests/ADT/SmallVectorTest.cpp
+++ llvm/unittests/ADT/SmallVectorTest.cpp
@@ -226,6 +226,22 @@
   this->assertValuesInOrder(this->theVector, 3u, 1, 2, 3);
 }
 
+// Constructor test.
+TYPED_TEST(SmallVectorTest, ConstructorIterableCArrayTest) {
+  SCOPED_TRACE("ConstructorTest");
+  int arr[] = {1, 2, 3};
+  this->theVector = SmallVector<Constructable, 4>(arr);
+  this->assertValuesInOrder(this->theVector, 3u, 1, 2, 3);
+}
+
+// Constructor test.
+TYPED_TEST(SmallVectorTest, ConstructorIterableVectorTest) {
+  SCOPED_TRACE("ConstructorTest");
+  std::vector<int> vec = {1, 2, 3};
+  this->theVector = SmallVector<Constructable, 4>(vec);
+  this->assertValuesInOrder(this->theVector, 3u, 1, 2, 3);
+}
+
 // New vector test.
 TYPED_TEST(SmallVectorTest, EmptyVectorTest) {
   SCOPED_TRACE("EmptyVectorTest");
Index: llvm/unittests/ADT/IterableTraitsTest.cpp
===================================================================
--- /dev/null
+++ llvm/unittests/ADT/IterableTraitsTest.cpp
@@ -0,0 +1,62 @@
+//===- IterableTraitsTest.cpp - Unit tests for is_range_iterable ----------===//
+//
+// 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/IterableTraits.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/iterator_range.h"
+#include "gtest/gtest.h"
+#include <array>
+#include <forward_list>
+#include <vector>
+
+namespace llvm {
+
+class ForwardDeclared;
+
+TEST(IteratorRangeTest, IsForwardIterator) {
+  EXPECT_FALSE(is_forward_iterator<int>::value);
+  EXPECT_TRUE(is_forward_iterator<int *>::value);
+  EXPECT_TRUE(is_forward_iterator<ForwardDeclared *>::value);
+  EXPECT_TRUE(is_forward_iterator<const ForwardDeclared *>::value);
+  using ForwardList = std::forward_list<int>;
+  EXPECT_TRUE(is_forward_iterator<ForwardList::iterator>::value);
+  EXPECT_TRUE(is_forward_iterator<ForwardList::const_iterator>::value);
+}
+
+TEST(IteratorRangeTest, IsIterableCArray) {
+  int Data[4];
+  EXPECT_TRUE(
+      is_range_iterable<std::add_lvalue_reference_t<decltype(Data)>>::value);
+}
+
+TEST(IteratorRangeTest, IsIterableVector) {
+  using Vector = std::vector<int>;
+  EXPECT_TRUE(is_range_iterable<Vector>::value);
+}
+
+TEST(IteratorRangeTest, IsIterableArray) {
+  using Array = std::array<int, 3>;
+  EXPECT_TRUE(is_range_iterable<Array>::value);
+}
+
+TEST(IteratorRangeTest, IsIterableSmallVector) {
+  using SVector = SmallVector<int, 3>;
+  EXPECT_TRUE(is_range_iterable<SVector>::value);
+}
+
+TEST(IteratorRangeTest, IsIterableRange) {
+  using Range = iterator_range<const ForwardDeclared *>;
+  EXPECT_TRUE(is_range_iterable<Range>::value);
+}
+
+TEST(IteratorRangeTest, NonIterableTypes) {
+  EXPECT_FALSE(is_range_iterable<int>::value);
+  EXPECT_FALSE(is_range_iterable<ForwardDeclared>::value);
+}
+
+} // namespace llvm
Index: llvm/unittests/ADT/CMakeLists.txt
===================================================================
--- llvm/unittests/ADT/CMakeLists.txt
+++ llvm/unittests/ADT/CMakeLists.txt
@@ -41,6 +41,7 @@
   IntEqClassesTest.cpp
   IntervalMapTest.cpp
   IntrusiveRefCntPtrTest.cpp
+  IterableTraitsTest.cpp
   IteratorTest.cpp
   MappedIteratorTest.cpp
   MapVectorTest.cpp
Index: llvm/tools/llvm-xray/xray-converter.cpp
===================================================================
--- llvm/tools/llvm-xray/xray-converter.cpp
+++ llvm/tools/llvm-xray/xray-converter.cpp
@@ -158,6 +158,8 @@
 // A structure that allows building a dictionary of stack ids for the Chrome
 // trace event format.
 struct StackIdData {
+  StackIdData(const StackIdData &) = default;
+
   // Each Stack of function calls has a unique ID.
   unsigned id;
 
Index: llvm/include/llvm/ADT/SmallVector.h
===================================================================
--- llvm/include/llvm/ADT/SmallVector.h
+++ llvm/include/llvm/ADT/SmallVector.h
@@ -13,7 +13,7 @@
 #ifndef LLVM_ADT_SMALLVECTOR_H
 #define LLVM_ADT_SMALLVECTOR_H
 
-#include "llvm/ADT/iterator_range.h"
+#include "llvm/ADT/IterableTraits.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/MathExtras.h"
@@ -1188,10 +1188,13 @@
     this->append(S, E);
   }
 
-  template <typename RangeTy>
-  explicit SmallVector(const iterator_range<RangeTy> &R)
+  template <typename Iterable>
+  explicit SmallVector(
+      Iterable &&Range,
+      std::enable_if_t<llvm::is_range_iterable<Iterable>::value, bool> = true)
       : SmallVectorImpl<T>(N) {
-    this->append(R.begin(), R.end());
+    this->append(std::begin(std::forward<Iterable>(Range)),
+                 std::end(std::forward<Iterable>(Range)));
   }
 
   SmallVector(std::initializer_list<T> IL) : SmallVectorImpl<T>(N) {
Index: llvm/include/llvm/ADT/IterableTraits.h
===================================================================
--- /dev/null
+++ llvm/include/llvm/ADT/IterableTraits.h
@@ -0,0 +1,55 @@
+//===- IterableTraits.h - A trait to identify iterables ---------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_ITERABLETRAITS_H
+#define LLVM_ADT_ITERABLETRAITS_H
+
+#include <iterator>
+#include <type_traits>
+
+namespace llvm {
+
+namespace detail {
+
+template <typename I> auto is_forward_iterator(...) -> std::false_type;
+
+template <typename I>
+auto is_forward_iterator(int) -> decltype(
+    std::next(std::declval<I>()),
+    std::integral_constant<
+        bool,
+        std::is_convertible<decltype(std::declval<I>() != std::declval<I>()),
+                            bool>::value &&
+            !std::is_void<decltype(*std::declval<I>())>::value &&
+            std::is_copy_constructible<I>::value && true>{});
+
+} // namespace detail
+
+// A convenient trait to check whether a type provides the forward iterator
+// semantic.
+template <typename I>
+struct is_forward_iterator : decltype(detail::is_forward_iterator<I>(0)) {};
+
+namespace detail {
+
+template <typename T> auto is_range_iterable(...) -> std::false_type;
+
+template <typename T, typename I = typename std::decay_t<
+                          decltype(std::begin(std::declval<T>()))>>
+auto is_range_iterable(char) -> decltype(std::begin(std::declval<T>()), //
+                                         std::end(std::declval<T>()),   //
+                                         llvm::is_forward_iterator<I>{});
+} // namespace detail
+
+// A convenient trait to check whether a type provides the begin / end semantic.
+template <typename T>
+struct is_range_iterable : decltype(detail::is_range_iterable<T>(0)) {};
+
+} // namespace llvm
+
+#endif // LLVM_ADT_ITERABLETRAITS_H
Index: clang/include/clang/Basic/Module.h
===================================================================
--- clang/include/clang/Basic/Module.h
+++ clang/include/clang/Basic/Module.h
@@ -95,6 +95,8 @@
 /// Describes a module or submodule.
 class Module {
 public:
+  Module(const Module &) = default;
+
   /// The name of this module.
   std::string Name;
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to