Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 1
//===- ArrayRef.h - Array Reference Wrapper ---------------------*- C++ -*-===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
 
9
#ifndef LLVM_ADT_ARRAYREF_H
10
#define LLVM_ADT_ARRAYREF_H
11
 
12
#include "llvm/ADT/Hashing.h"
13
#include "llvm/ADT/SmallVector.h"
14
#include "llvm/ADT/STLExtras.h"
15
#include "llvm/Support/Compiler.h"
16
#include <algorithm>
17
#include <array>
18
#include <cassert>
19
#include <cstddef>
20
#include <initializer_list>
21
#include <iterator>
22
#include <memory>
23
#include <type_traits>
24
#include <vector>
25
 
26
namespace llvm {
27
  template<typename T> class [[nodiscard]] MutableArrayRef;
28
 
29
  /// ArrayRef - Represent a constant reference to an array (0 or more elements
30
  /// consecutively in memory), i.e. a start pointer and a length.  It allows
31
  /// various APIs to take consecutive elements easily and conveniently.
32
  ///
33
  /// This class does not own the underlying data, it is expected to be used in
34
  /// situations where the data resides in some other buffer, whose lifetime
35
  /// extends past that of the ArrayRef. For this reason, it is not in general
36
  /// safe to store an ArrayRef.
37
  ///
38
  /// This is intended to be trivially copyable, so it should be passed by
39
  /// value.
40
  template<typename T>
41
  class LLVM_GSL_POINTER [[nodiscard]] ArrayRef {
42
  public:
43
    using value_type = T;
44
    using pointer = value_type *;
45
    using const_pointer = const value_type *;
46
    using reference = value_type &;
47
    using const_reference = const value_type &;
48
    using iterator = const_pointer;
49
    using const_iterator = const_pointer;
50
    using reverse_iterator = std::reverse_iterator<iterator>;
51
    using const_reverse_iterator = std::reverse_iterator<const_iterator>;
52
    using size_type = size_t;
53
    using difference_type = ptrdiff_t;
54
 
55
  private:
56
    /// The start of the array, in an external buffer.
57
    const T *Data = nullptr;
58
 
59
    /// The number of elements.
60
    size_type Length = 0;
61
 
62
  public:
63
    /// @name Constructors
64
    /// @{
65
 
66
    /// Construct an empty ArrayRef.
67
    /*implicit*/ ArrayRef() = default;
68
 
69
    /// Construct an empty ArrayRef from std::nullopt.
70
    /*implicit*/ ArrayRef(std::nullopt_t) {}
71
 
72
    /// Construct an ArrayRef from a single element.
73
    /*implicit*/ ArrayRef(const T &OneElt)
74
      : Data(&OneElt), Length(1) {}
75
 
76
    /// Construct an ArrayRef from a pointer and length.
77
    constexpr /*implicit*/ ArrayRef(const T *data, size_t length)
78
        : Data(data), Length(length) {}
79
 
80
    /// Construct an ArrayRef from a range.
81
    constexpr ArrayRef(const T *begin, const T *end)
82
        : Data(begin), Length(end - begin) {}
83
 
84
    /// Construct an ArrayRef from a SmallVector. This is templated in order to
85
    /// avoid instantiating SmallVectorTemplateCommon<T> whenever we
86
    /// copy-construct an ArrayRef.
87
    template<typename U>
88
    /*implicit*/ ArrayRef(const SmallVectorTemplateCommon<T, U> &Vec)
89
      : Data(Vec.data()), Length(Vec.size()) {
90
    }
91
 
92
    /// Construct an ArrayRef from a std::vector.
93
    template<typename A>
94
    /*implicit*/ ArrayRef(const std::vector<T, A> &Vec)
95
      : Data(Vec.data()), Length(Vec.size()) {}
96
 
97
    /// Construct an ArrayRef from a std::array
98
    template <size_t N>
99
    /*implicit*/ constexpr ArrayRef(const std::array<T, N> &Arr)
100
        : Data(Arr.data()), Length(N) {}
101
 
102
    /// Construct an ArrayRef from a C array.
103
    template <size_t N>
104
    /*implicit*/ constexpr ArrayRef(const T (&Arr)[N]) : Data(Arr), Length(N) {}
105
 
106
    /// Construct an ArrayRef from a std::initializer_list.
107
#if LLVM_GNUC_PREREQ(9, 0, 0)
108
// Disable gcc's warning in this constructor as it generates an enormous amount
109
// of messages. Anyone using ArrayRef should already be aware of the fact that
110
// it does not do lifetime extension.
111
#pragma GCC diagnostic push
112
#pragma GCC diagnostic ignored "-Winit-list-lifetime"
113
#endif
114
    constexpr /*implicit*/ ArrayRef(const std::initializer_list<T> &Vec)
115
        : Data(Vec.begin() == Vec.end() ? (T *)nullptr : Vec.begin()),
116
          Length(Vec.size()) {}
117
#if LLVM_GNUC_PREREQ(9, 0, 0)
118
#pragma GCC diagnostic pop
119
#endif
120
 
121
    /// Construct an ArrayRef<const T*> from ArrayRef<T*>. This uses SFINAE to
122
    /// ensure that only ArrayRefs of pointers can be converted.
123
    template <typename U>
124
    ArrayRef(const ArrayRef<U *> &A,
125
             std::enable_if_t<std::is_convertible<U *const *, T const *>::value>
126
                 * = nullptr)
127
        : Data(A.data()), Length(A.size()) {}
128
 
129
    /// Construct an ArrayRef<const T*> from a SmallVector<T*>. This is
130
    /// templated in order to avoid instantiating SmallVectorTemplateCommon<T>
131
    /// whenever we copy-construct an ArrayRef.
132
    template <typename U, typename DummyT>
133
    /*implicit*/ ArrayRef(
134
        const SmallVectorTemplateCommon<U *, DummyT> &Vec,
135
        std::enable_if_t<std::is_convertible<U *const *, T const *>::value> * =
136
            nullptr)
137
        : Data(Vec.data()), Length(Vec.size()) {}
138
 
139
    /// Construct an ArrayRef<const T*> from std::vector<T*>. This uses SFINAE
140
    /// to ensure that only vectors of pointers can be converted.
141
    template <typename U, typename A>
142
    ArrayRef(const std::vector<U *, A> &Vec,
143
             std::enable_if_t<std::is_convertible<U *const *, T const *>::value>
144
                 * = nullptr)
145
        : Data(Vec.data()), Length(Vec.size()) {}
146
 
147
    /// @}
148
    /// @name Simple Operations
149
    /// @{
150
 
151
    iterator begin() const { return Data; }
152
    iterator end() const { return Data + Length; }
153
 
154
    reverse_iterator rbegin() const { return reverse_iterator(end()); }
155
    reverse_iterator rend() const { return reverse_iterator(begin()); }
156
 
157
    /// empty - Check if the array is empty.
158
    bool empty() const { return Length == 0; }
159
 
160
    const T *data() const { return Data; }
161
 
162
    /// size - Get the array size.
163
    size_t size() const { return Length; }
164
 
165
    /// front - Get the first element.
166
    const T &front() const {
167
      assert(!empty());
168
      return Data[0];
169
    }
170
 
171
    /// back - Get the last element.
172
    const T &back() const {
173
      assert(!empty());
174
      return Data[Length-1];
175
    }
176
 
177
    // copy - Allocate copy in Allocator and return ArrayRef<T> to it.
178
    template <typename Allocator> MutableArrayRef<T> copy(Allocator &A) {
179
      T *Buff = A.template Allocate<T>(Length);
180
      std::uninitialized_copy(begin(), end(), Buff);
181
      return MutableArrayRef<T>(Buff, Length);
182
    }
183
 
184
    /// equals - Check for element-wise equality.
185
    bool equals(ArrayRef RHS) const {
186
      if (Length != RHS.Length)
187
        return false;
188
      return std::equal(begin(), end(), RHS.begin());
189
    }
190
 
191
    /// slice(n, m) - Chop off the first N elements of the array, and keep M
192
    /// elements in the array.
193
    ArrayRef<T> slice(size_t N, size_t M) const {
194
      assert(N+M <= size() && "Invalid specifier");
195
      return ArrayRef<T>(data()+N, M);
196
    }
197
 
198
    /// slice(n) - Chop off the first N elements of the array.
199
    ArrayRef<T> slice(size_t N) const { return slice(N, size() - N); }
200
 
201
    /// Drop the first \p N elements of the array.
202
    ArrayRef<T> drop_front(size_t N = 1) const {
203
      assert(size() >= N && "Dropping more elements than exist");
204
      return slice(N, size() - N);
205
    }
206
 
207
    /// Drop the last \p N elements of the array.
208
    ArrayRef<T> drop_back(size_t N = 1) const {
209
      assert(size() >= N && "Dropping more elements than exist");
210
      return slice(0, size() - N);
211
    }
212
 
213
    /// Return a copy of *this with the first N elements satisfying the
214
    /// given predicate removed.
215
    template <class PredicateT> ArrayRef<T> drop_while(PredicateT Pred) const {
216
      return ArrayRef<T>(find_if_not(*this, Pred), end());
217
    }
218
 
219
    /// Return a copy of *this with the first N elements not satisfying
220
    /// the given predicate removed.
221
    template <class PredicateT> ArrayRef<T> drop_until(PredicateT Pred) const {
222
      return ArrayRef<T>(find_if(*this, Pred), end());
223
    }
224
 
225
    /// Return a copy of *this with only the first \p N elements.
226
    ArrayRef<T> take_front(size_t N = 1) const {
227
      if (N >= size())
228
        return *this;
229
      return drop_back(size() - N);
230
    }
231
 
232
    /// Return a copy of *this with only the last \p N elements.
233
    ArrayRef<T> take_back(size_t N = 1) const {
234
      if (N >= size())
235
        return *this;
236
      return drop_front(size() - N);
237
    }
238
 
239
    /// Return the first N elements of this Array that satisfy the given
240
    /// predicate.
241
    template <class PredicateT> ArrayRef<T> take_while(PredicateT Pred) const {
242
      return ArrayRef<T>(begin(), find_if_not(*this, Pred));
243
    }
244
 
245
    /// Return the first N elements of this Array that don't satisfy the
246
    /// given predicate.
247
    template <class PredicateT> ArrayRef<T> take_until(PredicateT Pred) const {
248
      return ArrayRef<T>(begin(), find_if(*this, Pred));
249
    }
250
 
251
    /// @}
252
    /// @name Operator Overloads
253
    /// @{
254
    const T &operator[](size_t Index) const {
255
      assert(Index < Length && "Invalid index!");
256
      return Data[Index];
257
    }
258
 
259
    /// Disallow accidental assignment from a temporary.
260
    ///
261
    /// The declaration here is extra complicated so that "arrayRef = {}"
262
    /// continues to select the move assignment operator.
263
    template <typename U>
264
    std::enable_if_t<std::is_same<U, T>::value, ArrayRef<T>> &
265
    operator=(U &&Temporary) = delete;
266
 
267
    /// Disallow accidental assignment from a temporary.
268
    ///
269
    /// The declaration here is extra complicated so that "arrayRef = {}"
270
    /// continues to select the move assignment operator.
271
    template <typename U>
272
    std::enable_if_t<std::is_same<U, T>::value, ArrayRef<T>> &
273
    operator=(std::initializer_list<U>) = delete;
274
 
275
    /// @}
276
    /// @name Expensive Operations
277
    /// @{
278
    std::vector<T> vec() const {
279
      return std::vector<T>(Data, Data+Length);
280
    }
281
 
282
    /// @}
283
    /// @name Conversion operators
284
    /// @{
285
    operator std::vector<T>() const {
286
      return std::vector<T>(Data, Data+Length);
287
    }
288
 
289
    /// @}
290
  };
291
 
292
  /// MutableArrayRef - Represent a mutable reference to an array (0 or more
293
  /// elements consecutively in memory), i.e. a start pointer and a length.  It
294
  /// allows various APIs to take and modify consecutive elements easily and
295
  /// conveniently.
296
  ///
297
  /// This class does not own the underlying data, it is expected to be used in
298
  /// situations where the data resides in some other buffer, whose lifetime
299
  /// extends past that of the MutableArrayRef. For this reason, it is not in
300
  /// general safe to store a MutableArrayRef.
301
  ///
302
  /// This is intended to be trivially copyable, so it should be passed by
303
  /// value.
304
  template<typename T>
305
  class [[nodiscard]] MutableArrayRef : public ArrayRef<T> {
306
  public:
307
    using value_type = T;
308
    using pointer = value_type *;
309
    using const_pointer = const value_type *;
310
    using reference = value_type &;
311
    using const_reference = const value_type &;
312
    using iterator = pointer;
313
    using const_iterator = const_pointer;
314
    using reverse_iterator = std::reverse_iterator<iterator>;
315
    using const_reverse_iterator = std::reverse_iterator<const_iterator>;
316
    using size_type = size_t;
317
    using difference_type = ptrdiff_t;
318
 
319
    /// Construct an empty MutableArrayRef.
320
    /*implicit*/ MutableArrayRef() = default;
321
 
322
    /// Construct an empty MutableArrayRef from std::nullopt.
323
    /*implicit*/ MutableArrayRef(std::nullopt_t) : ArrayRef<T>() {}
324
 
325
    /// Construct a MutableArrayRef from a single element.
326
    /*implicit*/ MutableArrayRef(T &OneElt) : ArrayRef<T>(OneElt) {}
327
 
328
    /// Construct a MutableArrayRef from a pointer and length.
329
    /*implicit*/ MutableArrayRef(T *data, size_t length)
330
      : ArrayRef<T>(data, length) {}
331
 
332
    /// Construct a MutableArrayRef from a range.
333
    MutableArrayRef(T *begin, T *end) : ArrayRef<T>(begin, end) {}
334
 
335
    /// Construct a MutableArrayRef from a SmallVector.
336
    /*implicit*/ MutableArrayRef(SmallVectorImpl<T> &Vec)
337
    : ArrayRef<T>(Vec) {}
338
 
339
    /// Construct a MutableArrayRef from a std::vector.
340
    /*implicit*/ MutableArrayRef(std::vector<T> &Vec)
341
    : ArrayRef<T>(Vec) {}
342
 
343
    /// Construct a MutableArrayRef from a std::array
344
    template <size_t N>
345
    /*implicit*/ constexpr MutableArrayRef(std::array<T, N> &Arr)
346
        : ArrayRef<T>(Arr) {}
347
 
348
    /// Construct a MutableArrayRef from a C array.
349
    template <size_t N>
350
    /*implicit*/ constexpr MutableArrayRef(T (&Arr)[N]) : ArrayRef<T>(Arr) {}
351
 
352
    T *data() const { return const_cast<T*>(ArrayRef<T>::data()); }
353
 
354
    iterator begin() const { return data(); }
355
    iterator end() const { return data() + this->size(); }
356
 
357
    reverse_iterator rbegin() const { return reverse_iterator(end()); }
358
    reverse_iterator rend() const { return reverse_iterator(begin()); }
359
 
360
    /// front - Get the first element.
361
    T &front() const {
362
      assert(!this->empty());
363
      return data()[0];
364
    }
365
 
366
    /// back - Get the last element.
367
    T &back() const {
368
      assert(!this->empty());
369
      return data()[this->size()-1];
370
    }
371
 
372
    /// slice(n, m) - Chop off the first N elements of the array, and keep M
373
    /// elements in the array.
374
    MutableArrayRef<T> slice(size_t N, size_t M) const {
375
      assert(N + M <= this->size() && "Invalid specifier");
376
      return MutableArrayRef<T>(this->data() + N, M);
377
    }
378
 
379
    /// slice(n) - Chop off the first N elements of the array.
380
    MutableArrayRef<T> slice(size_t N) const {
381
      return slice(N, this->size() - N);
382
    }
383
 
384
    /// Drop the first \p N elements of the array.
385
    MutableArrayRef<T> drop_front(size_t N = 1) const {
386
      assert(this->size() >= N && "Dropping more elements than exist");
387
      return slice(N, this->size() - N);
388
    }
389
 
390
    MutableArrayRef<T> drop_back(size_t N = 1) const {
391
      assert(this->size() >= N && "Dropping more elements than exist");
392
      return slice(0, this->size() - N);
393
    }
394
 
395
    /// Return a copy of *this with the first N elements satisfying the
396
    /// given predicate removed.
397
    template <class PredicateT>
398
    MutableArrayRef<T> drop_while(PredicateT Pred) const {
399
      return MutableArrayRef<T>(find_if_not(*this, Pred), end());
400
    }
401
 
402
    /// Return a copy of *this with the first N elements not satisfying
403
    /// the given predicate removed.
404
    template <class PredicateT>
405
    MutableArrayRef<T> drop_until(PredicateT Pred) const {
406
      return MutableArrayRef<T>(find_if(*this, Pred), end());
407
    }
408
 
409
    /// Return a copy of *this with only the first \p N elements.
410
    MutableArrayRef<T> take_front(size_t N = 1) const {
411
      if (N >= this->size())
412
        return *this;
413
      return drop_back(this->size() - N);
414
    }
415
 
416
    /// Return a copy of *this with only the last \p N elements.
417
    MutableArrayRef<T> take_back(size_t N = 1) const {
418
      if (N >= this->size())
419
        return *this;
420
      return drop_front(this->size() - N);
421
    }
422
 
423
    /// Return the first N elements of this Array that satisfy the given
424
    /// predicate.
425
    template <class PredicateT>
426
    MutableArrayRef<T> take_while(PredicateT Pred) const {
427
      return MutableArrayRef<T>(begin(), find_if_not(*this, Pred));
428
    }
429
 
430
    /// Return the first N elements of this Array that don't satisfy the
431
    /// given predicate.
432
    template <class PredicateT>
433
    MutableArrayRef<T> take_until(PredicateT Pred) const {
434
      return MutableArrayRef<T>(begin(), find_if(*this, Pred));
435
    }
436
 
437
    /// @}
438
    /// @name Operator Overloads
439
    /// @{
440
    T &operator[](size_t Index) const {
441
      assert(Index < this->size() && "Invalid index!");
442
      return data()[Index];
443
    }
444
  };
445
 
446
  /// This is a MutableArrayRef that owns its array.
447
  template <typename T> class OwningArrayRef : public MutableArrayRef<T> {
448
  public:
449
    OwningArrayRef() = default;
450
    OwningArrayRef(size_t Size) : MutableArrayRef<T>(new T[Size], Size) {}
451
 
452
    OwningArrayRef(ArrayRef<T> Data)
453
        : MutableArrayRef<T>(new T[Data.size()], Data.size()) {
454
      std::copy(Data.begin(), Data.end(), this->begin());
455
    }
456
 
457
    OwningArrayRef(OwningArrayRef &&Other) { *this = std::move(Other); }
458
 
459
    OwningArrayRef &operator=(OwningArrayRef &&Other) {
460
      delete[] this->data();
461
      this->MutableArrayRef<T>::operator=(Other);
462
      Other.MutableArrayRef<T>::operator=(MutableArrayRef<T>());
463
      return *this;
464
    }
465
 
466
    ~OwningArrayRef() { delete[] this->data(); }
467
  };
468
 
469
  /// @name ArrayRef Deduction guides
470
  /// @{
471
  /// Deduction guide to construct an ArrayRef from a single element.
472
  template <typename T> ArrayRef(const T &OneElt) -> ArrayRef<T>;
473
 
474
  /// Deduction guide to construct an ArrayRef from a pointer and length
475
  template <typename T> ArrayRef(const T *data, size_t length) -> ArrayRef<T>;
476
 
477
  /// Deduction guide to construct an ArrayRef from a range
478
  template <typename T> ArrayRef(const T *data, const T *end) -> ArrayRef<T>;
479
 
480
  /// Deduction guide to construct an ArrayRef from a SmallVector
481
  template <typename T> ArrayRef(const SmallVectorImpl<T> &Vec) -> ArrayRef<T>;
482
 
483
  /// Deduction guide to construct an ArrayRef from a SmallVector
484
  template <typename T, unsigned N>
485
  ArrayRef(const SmallVector<T, N> &Vec) -> ArrayRef<T>;
486
 
487
  /// Deduction guide to construct an ArrayRef from a std::vector
488
  template <typename T> ArrayRef(const std::vector<T> &Vec) -> ArrayRef<T>;
489
 
490
  /// Deduction guide to construct an ArrayRef from a std::array
491
  template <typename T, std::size_t N>
492
  ArrayRef(const std::array<T, N> &Vec) -> ArrayRef<T>;
493
 
494
  /// Deduction guide to construct an ArrayRef from an ArrayRef (const)
495
  template <typename T> ArrayRef(const ArrayRef<T> &Vec) -> ArrayRef<T>;
496
 
497
  /// Deduction guide to construct an ArrayRef from an ArrayRef
498
  template <typename T> ArrayRef(ArrayRef<T> &Vec) -> ArrayRef<T>;
499
 
500
  /// Deduction guide to construct an ArrayRef from a C array.
501
  template <typename T, size_t N> ArrayRef(const T (&Arr)[N]) -> ArrayRef<T>;
502
 
503
  /// @}
504
 
505
  /// @name ArrayRef Convenience constructors
506
  /// @{
507
  /// Construct an ArrayRef from a single element.
508
  template <typename T>
509
  LLVM_DEPRECATED("Use deduction guide instead", "ArrayRef")
510
  ArrayRef<T> makeArrayRef(const T &OneElt) {
511
    return OneElt;
512
  }
513
 
514
  /// Construct an ArrayRef from a pointer and length.
515
  template <typename T>
516
  LLVM_DEPRECATED("Use deduction guide instead", "ArrayRef")
517
  ArrayRef<T> makeArrayRef(const T *data, size_t length) {
518
    return ArrayRef<T>(data, length);
519
  }
520
 
521
  /// Construct an ArrayRef from a range.
522
  template <typename T>
523
  LLVM_DEPRECATED("Use deduction guide instead", "ArrayRef")
524
  ArrayRef<T> makeArrayRef(const T *begin, const T *end) {
525
    return ArrayRef<T>(begin, end);
526
  }
527
 
528
  /// Construct an ArrayRef from a SmallVector.
529
  template <typename T>
530
  LLVM_DEPRECATED("Use deduction guide instead", "ArrayRef")
531
  ArrayRef<T> makeArrayRef(const SmallVectorImpl<T> &Vec) {
532
    return Vec;
533
  }
534
 
535
  /// Construct an ArrayRef from a SmallVector.
536
  template <typename T, unsigned N>
537
  LLVM_DEPRECATED("Use deduction guide instead", "ArrayRef")
538
  ArrayRef<T> makeArrayRef(const SmallVector<T, N> &Vec) {
539
    return Vec;
540
  }
541
 
542
  /// Construct an ArrayRef from a std::vector.
543
  template <typename T>
544
  LLVM_DEPRECATED("Use deduction guide instead", "ArrayRef")
545
  ArrayRef<T> makeArrayRef(const std::vector<T> &Vec) {
546
    return Vec;
547
  }
548
 
549
  /// Construct an ArrayRef from a std::array.
550
  template <typename T, std::size_t N>
551
  LLVM_DEPRECATED("Use deduction guide instead", "ArrayRef")
552
  ArrayRef<T> makeArrayRef(const std::array<T, N> &Arr) {
553
    return Arr;
554
  }
555
 
556
  /// Construct an ArrayRef from an ArrayRef (no-op) (const)
557
  template <typename T>
558
  LLVM_DEPRECATED("Use deduction guide instead", "ArrayRef")
559
  ArrayRef<T> makeArrayRef(const ArrayRef<T> &Vec) {
560
    return Vec;
561
  }
562
 
563
  /// Construct an ArrayRef from an ArrayRef (no-op)
564
  template <typename T>
565
  LLVM_DEPRECATED("Use deduction guide instead", "ArrayRef")
566
  ArrayRef<T> &makeArrayRef(ArrayRef<T> &Vec) {
567
    return Vec;
568
  }
569
 
570
  /// Construct an ArrayRef from a C array.
571
  template <typename T, size_t N>
572
  LLVM_DEPRECATED("Use deduction guide instead", "ArrayRef")
573
  ArrayRef<T> makeArrayRef(const T (&Arr)[N]) {
574
    return ArrayRef<T>(Arr);
575
  }
576
 
577
  /// @name MutableArrayRef Deduction guides
578
  /// @{
579
  /// Deduction guide to construct a `MutableArrayRef` from a single element
580
  template <class T> MutableArrayRef(T &OneElt) -> MutableArrayRef<T>;
581
 
582
  /// Deduction guide to construct a `MutableArrayRef` from a pointer and
583
  /// length.
584
  template <class T>
585
  MutableArrayRef(T *data, size_t length) -> MutableArrayRef<T>;
586
 
587
  /// Deduction guide to construct a `MutableArrayRef` from a `SmallVector`.
588
  template <class T>
589
  MutableArrayRef(SmallVectorImpl<T> &Vec) -> MutableArrayRef<T>;
590
 
591
  template <class T, unsigned N>
592
  MutableArrayRef(SmallVector<T, N> &Vec) -> MutableArrayRef<T>;
593
 
594
  /// Deduction guide to construct a `MutableArrayRef` from a `std::vector`.
595
  template <class T> MutableArrayRef(std::vector<T> &Vec) -> MutableArrayRef<T>;
596
 
597
  /// Deduction guide to construct a `MutableArrayRef` from a `std::array`.
598
  template <class T, std::size_t N>
599
  MutableArrayRef(std::array<T, N> &Vec) -> MutableArrayRef<T>;
600
 
601
  /// Deduction guide to construct a `MutableArrayRef` from a C array.
602
  template <typename T, size_t N>
603
  MutableArrayRef(T (&Arr)[N]) -> MutableArrayRef<T>;
604
 
605
  /// @}
606
 
607
  /// Construct a MutableArrayRef from a single element.
608
  template <typename T>
609
  LLVM_DEPRECATED("Use deduction guide instead", "MutableArrayRef")
610
  MutableArrayRef<T> makeMutableArrayRef(T &OneElt) {
611
    return OneElt;
612
  }
613
 
614
  /// Construct a MutableArrayRef from a pointer and length.
615
  template <typename T>
616
  LLVM_DEPRECATED("Use deduction guide instead", "MutableArrayRef")
617
  MutableArrayRef<T> makeMutableArrayRef(T *data, size_t length) {
618
    return MutableArrayRef<T>(data, length);
619
  }
620
 
621
  /// Construct a MutableArrayRef from a SmallVector.
622
  template <typename T>
623
  LLVM_DEPRECATED("Use deduction guide instead", "MutableArrayRef")
624
  MutableArrayRef<T> makeMutableArrayRef(SmallVectorImpl<T> &Vec) {
625
    return Vec;
626
  }
627
 
628
  /// Construct a MutableArrayRef from a SmallVector.
629
  template <typename T, unsigned N>
630
  LLVM_DEPRECATED("Use deduction guide instead", "MutableArrayRef")
631
  MutableArrayRef<T> makeMutableArrayRef(SmallVector<T, N> &Vec) {
632
    return Vec;
633
  }
634
 
635
  /// Construct a MutableArrayRef from a std::vector.
636
  template <typename T>
637
  LLVM_DEPRECATED("Use deduction guide instead", "MutableArrayRef")
638
  MutableArrayRef<T> makeMutableArrayRef(std::vector<T> &Vec) {
639
    return Vec;
640
  }
641
 
642
  /// Construct a MutableArrayRef from a std::array.
643
  template <typename T, std::size_t N>
644
  LLVM_DEPRECATED("Use deduction guide instead", "MutableArrayRef")
645
  MutableArrayRef<T> makeMutableArrayRef(std::array<T, N> &Arr) {
646
    return Arr;
647
  }
648
 
649
  /// Construct a MutableArrayRef from a MutableArrayRef (no-op) (const)
650
  template <typename T>
651
  LLVM_DEPRECATED("Use deduction guide instead", "MutableArrayRef")
652
  MutableArrayRef<T> makeMutableArrayRef(const MutableArrayRef<T> &Vec) {
653
    return Vec;
654
  }
655
 
656
  /// Construct a MutableArrayRef from a C array.
657
  template <typename T, size_t N>
658
  LLVM_DEPRECATED("Use deduction guide instead", "MutableArrayRef")
659
  MutableArrayRef<T> makeMutableArrayRef(T (&Arr)[N]) {
660
    return MutableArrayRef<T>(Arr);
661
  }
662
 
663
  /// @}
664
  /// @name ArrayRef Comparison Operators
665
  /// @{
666
 
667
  template<typename T>
668
  inline bool operator==(ArrayRef<T> LHS, ArrayRef<T> RHS) {
669
    return LHS.equals(RHS);
670
  }
671
 
672
  template <typename T>
673
  inline bool operator==(SmallVectorImpl<T> &LHS, ArrayRef<T> RHS) {
674
    return ArrayRef<T>(LHS).equals(RHS);
675
  }
676
 
677
  template <typename T>
678
  inline bool operator!=(ArrayRef<T> LHS, ArrayRef<T> RHS) {
679
    return !(LHS == RHS);
680
  }
681
 
682
  template <typename T>
683
  inline bool operator!=(SmallVectorImpl<T> &LHS, ArrayRef<T> RHS) {
684
    return !(LHS == RHS);
685
  }
686
 
687
  /// @}
688
 
689
  template <typename T> hash_code hash_value(ArrayRef<T> S) {
690
    return hash_combine_range(S.begin(), S.end());
691
  }
692
 
693
  // Provide DenseMapInfo for ArrayRefs.
694
  template <typename T> struct DenseMapInfo<ArrayRef<T>, void> {
695
    static inline ArrayRef<T> getEmptyKey() {
696
      return ArrayRef<T>(
697
          reinterpret_cast<const T *>(~static_cast<uintptr_t>(0)), size_t(0));
698
    }
699
 
700
    static inline ArrayRef<T> getTombstoneKey() {
701
      return ArrayRef<T>(
702
          reinterpret_cast<const T *>(~static_cast<uintptr_t>(1)), size_t(0));
703
    }
704
 
705
    static unsigned getHashValue(ArrayRef<T> Val) {
706
      assert(Val.data() != getEmptyKey().data() &&
707
             "Cannot hash the empty key!");
708
      assert(Val.data() != getTombstoneKey().data() &&
709
             "Cannot hash the tombstone key!");
710
      return (unsigned)(hash_value(Val));
711
    }
712
 
713
    static bool isEqual(ArrayRef<T> LHS, ArrayRef<T> RHS) {
714
      if (RHS.data() == getEmptyKey().data())
715
        return LHS.data() == getEmptyKey().data();
716
      if (RHS.data() == getTombstoneKey().data())
717
        return LHS.data() == getTombstoneKey().data();
718
      return LHS == RHS;
719
    }
720
  };
721
 
722
} // end namespace llvm
723
 
724
#endif // LLVM_ADT_ARRAYREF_H