gchatelet updated this revision to Diff 346657. gchatelet added a comment. Herald added a project: clang. Herald added a subscriber: cfe-commits.
- Remove dependency on iterable_range header - Simplified implementation, added tests 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,12 @@ this->append(S, E); } - template <typename RangeTy> - explicit SmallVector(const iterator_range<RangeTy> &R) + template <typename Iterable> + explicit SmallVector( + Iterable &&R, + 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(R), std::end(R)); } 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