gchatelet updated this revision to Diff 346669.
gchatelet added a comment.
- Forward argument
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
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits