llvm.org GIT mirror llvm / 6f59475
Replace llvm::integer_sequence and friends with the C++14 standard version The implementation in libc++ takes O(1) compile time, ours was O(n). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@368990 91177308-0d34-0410-b5e6-96231b3b80d8 Benjamin Kramer a month ago
5 changed file(s) with 62 addition(s) and 79 deletion(s). Raw diff Collapse all Expand all
529529 template
530530 bool any_of(R &&range, UnaryPredicate P);
531531
532 template struct index_sequence;
533
534 template struct index_sequence_for;
535
536532 namespace detail {
537533
538534 using std::declval;
567563 std::tuple iterators;
568564
569565 protected:
570 template value_type deref(index_sequence) const {
566 template value_type deref(std::index_sequence) const {
571567 return value_type(*std::get(iterators)...);
572568 }
573569
574570 template
575 decltype(iterators) tup_inc(index_sequence) const {
571 decltype(iterators) tup_inc(std::index_sequence) const {
576572 return std::tuple(std::next(std::get(iterators))...);
577573 }
578574
579575 template
580 decltype(iterators) tup_dec(index_sequence) const {
576 decltype(iterators) tup_dec(std::index_sequence) const {
581577 return std::tuple(std::prev(std::get(iterators))...);
582578 }
583579
584580 public:
585581 zip_common(Iters &&... ts) : iterators(std::forward(ts)...) {}
586582
587 value_type operator*() { return deref(index_sequence_for{}); }
583 value_type operator*() { return deref(std::index_sequence_for{}); }
588584
589585 const value_type operator*() const {
590 return deref(index_sequence_for{});
586 return deref(std::index_sequence_for{});
591587 }
592588
593589 ZipType &operator++() {
594 iterators = tup_inc(index_sequence_for{});
590 iterators = tup_inc(std::index_sequence_for{});
595591 return *reinterpret_cast(this);
596592 }
597593
598594 ZipType &operator--() {
599595 static_assert(Base::IsBidirectional,
600596 "All inner iterators must be at least bidirectional.");
601 iterators = tup_dec(index_sequence_for{});
597 iterators = tup_dec(std::index_sequence_for{});
602598 return *reinterpret_cast(this);
603599 }
604600 };
617613 template
618614 class zip_shortest : public zip_common, Iters...> {
619615 template
620 bool test(const zip_shortest &other, index_sequence) const {
616 bool test(const zip_shortest &other,
617 std::index_sequence) const {
621618 return all_of(std::initializer_list{std::get(this->iterators) !=
622619 std::get(other.iterators)...},
623620 identity{});
629626 zip_shortest(Iters &&... ts) : Base(std::forward(ts)...) {}
630627
631628 bool operator==(const zip_shortest &other) const {
632 return !test(other, index_sequence_for{});
629 return !test(other, std::index_sequence_for{});
633630 }
634631 };
635632
645642 private:
646643 std::tuple ts;
647644
648 template iterator begin_impl(index_sequence) const {
645 template
646 iterator begin_impl(std::index_sequence) const {
649647 return iterator(std::begin(std::get(ts))...);
650648 }
651 template iterator end_impl(index_sequence) const {
649 template iterator end_impl(std::index_sequence) const {
652650 return iterator(std::end(std::get(ts))...);
653651 }
654652
655653 public:
656654 zippy(Args &&... ts_) : ts(std::forward(ts_)...) {}
657655
658 iterator begin() const { return begin_impl(index_sequence_for{}); }
659 iterator end() const { return end_impl(index_sequence_for{}); }
656 iterator begin() const {
657 return begin_impl(std::index_sequence_for{});
658 }
659 iterator end() const { return end_impl(std::index_sequence_for{}); }
660660 };
661661
662662 } // end namespace detail
726726
727727 template
728728 bool test(const zip_longest_iterator &other,
729 index_sequence) const {
729 std::index_sequence) const {
730730 return llvm::any_of(
731731 std::initializer_list{std::get(this->iterators) !=
732732 std::get(other.iterators)...},
733733 identity{});
734734 }
735735
736 template value_type deref(index_sequence) const {
736 template value_type deref(std::index_sequence) const {
737737 return value_type(
738738 deref_or_none(std::get(iterators), std::get(end_iterators))...);
739739 }
740740
741741 template
742 decltype(iterators) tup_inc(index_sequence) const {
742 decltype(iterators) tup_inc(std::index_sequence) const {
743743 return std::tuple(
744744 next_or_end(std::get(iterators), std::get(end_iterators))...);
745745 }
749749 : iterators(std::forward(ts.first)...),
750750 end_iterators(std::forward(ts.second)...) {}
751751
752 value_type operator*() { return deref(index_sequence_for{}); }
753
754 value_type operator*() const { return deref(index_sequence_for{}); }
752 value_type operator*() { return deref(std::index_sequence_for{}); }
753
754 value_type operator*() const {
755 return deref(std::index_sequence_for{});
756 }
755757
756758 zip_longest_iterator &operator++() {
757 iterators = tup_inc(index_sequence_for{});
759 iterators = tup_inc(std::index_sequence_for{});
758760 return *this;
759761 }
760762
761763 bool operator==(const zip_longest_iterator &other) const {
762 return !test(other, index_sequence_for{});
764 return !test(other, std::index_sequence_for{});
763765 }
764766 };
765767
776778 private:
777779 std::tuple ts;
778780
779 template iterator begin_impl(index_sequence) const {
781 template
782 iterator begin_impl(std::index_sequence) const {
780783 return iterator(std::make_pair(adl_begin(std::get(ts)),
781784 adl_end(std::get(ts)))...);
782785 }
783786
784 template iterator end_impl(index_sequence) const {
787 template iterator end_impl(std::index_sequence) const {
785788 return iterator(std::make_pair(adl_end(std::get(ts)),
786789 adl_end(std::get(ts)))...);
787790 }
789792 public:
790793 zip_longest_range(Args &&... ts_) : ts(std::forward(ts_)...) {}
791794
792 iterator begin() const { return begin_impl(index_sequence_for{}); }
793 iterator end() const { return end_impl(index_sequence_for{}); }
795 iterator begin() const {
796 return begin_impl(std::index_sequence_for{});
797 }
798 iterator end() const { return end_impl(std::index_sequence_for{}); }
794799 };
795800 } // namespace detail
796801
846851 /// Increments the first non-end iterator.
847852 ///
848853 /// It is an error to call this with all iterators at the end.
849 template void increment(index_sequence) {
854 template void increment(std::index_sequence) {
850855 // Build a sequence of functions to increment each iterator if possible.
851856 bool (concat_iterator::*IncrementHelperFns[])() = {
852857 &concat_iterator::incrementHelper...};
875880 /// reference.
876881 ///
877882 /// It is an error to call this with all iterators at the end.
878 template ValueT &get(index_sequence) const {
883 template ValueT &get(std::index_sequence) const {
879884 // Build a sequence of functions to get from iterator if possible.
880885 ValueT *(concat_iterator::*GetHelperFns[])() const = {
881886 &concat_iterator::getHelper...};
900905 using BaseT::operator++;
901906
902907 concat_iterator &operator++() {
903 increment(index_sequence_for());
908 increment(std::index_sequence_for());
904909 return *this;
905910 }
906911
907 ValueT &operator*() const { return get(index_sequence_for()); }
912 ValueT &operator*() const {
913 return get(std::index_sequence_for());
914 }
908915
909916 bool operator==(const concat_iterator &RHS) const {
910917 return Begins == RHS.Begins && Ends == RHS.Ends;
927934 private:
928935 std::tuple Ranges;
929936
930 template iterator begin_impl(index_sequence) {
937 template iterator begin_impl(std::index_sequence) {
931938 return iterator(std::get(Ranges)...);
932939 }
933 template iterator end_impl(index_sequence) {
940 template iterator end_impl(std::index_sequence) {
934941 return iterator(make_range(std::end(std::get(Ranges)),
935942 std::end(std::get(Ranges)))...);
936943 }
939946 concat_range(RangeTs &&... Ranges)
940947 : Ranges(std::forward(Ranges)...) {}
941948
942 iterator begin() { return begin_impl(index_sequence_for{}); }
943 iterator end() { return end_impl(index_sequence_for{}); }
949 iterator begin() { return begin_impl(std::index_sequence_for{}); }
950 iterator end() { return end_impl(std::index_sequence_for{}); }
944951 };
945952
946953 } // end namespace detail
988995 return func(lhs.first, rhs.first);
989996 }
990997 };
991
992 // A subset of N3658. More stuff can be added as-needed.
993
994 /// Represents a compile-time sequence of integers.
995 template struct integer_sequence {
996 using value_type = T;
997
998 static constexpr size_t size() { return sizeof...(I); }
999 };
1000
1001 /// Alias for the common case of a sequence of size_ts.
1002 template
1003 struct index_sequence : integer_sequence {};
1004
1005 template
1006 struct build_index_impl : build_index_impl {};
1007 template
1008 struct build_index_impl<0, I...> : index_sequence {};
1009
1010 /// Creates a compile-time integer sequence for a parameter pack.
1011 template
1012 struct index_sequence_for : build_index_impl {};
1013998
1014999 /// Utility type to build an inheritance chain that makes it easy to rank
10151000 /// overload candidates.
15791564 namespace detail {
15801565
15811566 template
1582 auto apply_tuple_impl(F &&f, Tuple &&t, index_sequence)
1567 auto apply_tuple_impl(F &&f, Tuple &&t, std::index_sequence)
15831568 -> decltype(std::forward(f)(std::get(std::forward(t))...)) {
15841569 return std::forward(f)(std::get(std::forward(t))...);
15851570 }
15921577 template
15931578 auto apply_tuple(F &&f, Tuple &&t) -> decltype(detail::apply_tuple_impl(
15941579 std::forward(f), std::forward(t),
1595 build_index_impl<
1580 std::make_index_sequence<
15961581 std::tuple_size::type>::value>{})) {
1597 using Indices = build_index_impl<
1582 using Indices = std::make_index_sequence<
15981583 std::tuple_size::type>::value>;
15991584
16001585 return detail::apply_tuple_impl(std::forward(f), std::forward(t),
550550
551551 /// RPC channel serialization for std::tuple.
552552 static Error serialize(ChannelT &C, const std::tuple &V) {
553 return serializeTupleHelper(C, V, llvm::index_sequence_for());
553 return serializeTupleHelper(C, V, std::index_sequence_for());
554554 }
555555
556556 /// RPC channel deserialization for std::tuple.
557557 static Error deserialize(ChannelT &C, std::tuple &V) {
558 return deserializeTupleHelper(C, V, llvm::index_sequence_for());
558 return deserializeTupleHelper(C, V, std::index_sequence_for());
559559 }
560560
561561 private:
562562 // Serialization helper for std::tuple.
563563 template
564564 static Error serializeTupleHelper(ChannelT &C, const std::tuple &V,
565 llvm::index_sequence _) {
565 std::index_sequence _) {
566566 return serializeSeq(C, std::get(V)...);
567567 }
568568
569569 // Serialization helper for std::tuple.
570570 template
571571 static Error deserializeTupleHelper(ChannelT &C, std::tuple &V,
572 llvm::index_sequence _) {
572 std::index_sequence _) {
573573 return deserializeSeq(C, std::get(V)...);
574574 }
575575 };
501501 static typename WrappedHandlerReturn::Type
502502 unpackAndRun(HandlerT &Handler, std::tuple &Args) {
503503 return unpackAndRunHelper(Handler, Args,
504 llvm::index_sequence_for());
504 std::index_sequence_for());
505505 }
506506
507507 // Call the given handler with the given arguments.
509509 static Error unpackAndRunAsync(HandlerT &Handler, ResponderT &Responder,
510510 std::tuple &Args) {
511511 return unpackAndRunAsyncHelper(Handler, Responder, Args,
512 llvm::index_sequence_for());
512 std::index_sequence_for());
513513 }
514514
515515 // Call the given handler with the given arguments.
539539 // Deserialize arguments from the channel.
540540 template
541541 static Error deserializeArgs(ChannelT &C, std::tuple &Args) {
542 return deserializeArgsHelper(C, Args,
543 llvm::index_sequence_for());
542 return deserializeArgsHelper(C, Args, std::index_sequence_for());
544543 }
545544
546545 private:
547546 template
548547 static Error deserializeArgsHelper(ChannelT &C, std::tuple &Args,
549 llvm::index_sequence _) {
548 std::index_sequence _) {
550549 return SequenceSerialization::deserialize(
551550 C, std::get(Args)...);
552551 }
555554 static typename WrappedHandlerReturn<
556555 typename HandlerTraits::ReturnType>::Type
557556 unpackAndRunHelper(HandlerT &Handler, ArgTuple &Args,
558 llvm::index_sequence) {
557 std::index_sequence) {
559558 return run(Handler, std::move(std::get(Args))...);
560559 }
561
562560
563561 template
564562 size_t... Indexes>
565563 static typename WrappedHandlerReturn<
566564 typename HandlerTraits::ReturnType>::Type
567565 unpackAndRunAsyncHelper(HandlerT &Handler, ResponderT &Responder,
568 ArgTuple &Args,
569 llvm::index_sequence) {
566 ArgTuple &Args, std::index_sequence) {
570567 return run(Handler, Responder, std::move(std::get(Args))...);
571568 }
572569 };
417417 typename PassT::Result
418418 getAnalysisResultUnpackTuple(AnalysisManagerT &AM, IRUnitT &IR,
419419 std::tuple Args,
420 llvm::index_sequence) {
420 std::index_sequence) {
421421 (void)Args;
422422 return AM.template getResult(IR, std::get(Args)...);
423423 }
434434 std::tuple Args) {
435435 return (getAnalysisResultUnpackTuple<
436436 PassT, IRUnitT>)(AM, IR, Args,
437 llvm::index_sequence_for{});
437 std::index_sequence_for{});
438438 }
439439
440440 } // namespace detail
2828 #include
2929 #include
3030 #include
31 #include
3132
3233 namespace llvm {
3334
9091
9192 template
9293 int snprint_tuple(char *Buffer, unsigned BufferSize,
93 index_sequence) const {
94 std::index_sequence) const {
9495 #ifdef _MSC_VER
9596 return _snprintf(Buffer, BufferSize, Fmt, std::get(Vals)...);
9697 #else
105106 }
106107
107108 int snprint(char *Buffer, unsigned BufferSize) const override {
108 return snprint_tuple(Buffer, BufferSize, index_sequence_for());
109 return snprint_tuple(Buffer, BufferSize, std::index_sequence_for());
109110 }
110111 };
111112