|
657 | 657 | }; |
658 | 658 |
|
659 | 659 | template<class T, size_t Extent> |
660 | | - cw-fixed-value(T (&)[Extent]) -> cw-fixed-value<T[Extent]>; // \expos |
| 660 | + @\exposid{cw-fixed-value}@(T (&)[Extent]) -> cw-fixed-value<T[Extent]>; // \expos |
661 | 661 |
|
662 | 662 | struct @\exposid{cw-operators}@ { // \expos |
663 | 663 | // unary operators |
664 | 664 | template<@\exposid{constexpr-param}@ T> |
665 | | - friend constexpr auto operator+(T) noexcept -> constant_wrapper<(+T::value)> { return {}; } |
| 665 | + friend constexpr auto operator+(T) noexcept -> constant_wrapper<(+T::value)> |
| 666 | + { return {}; } |
666 | 667 | template<@\exposid{constexpr-param}@ T> |
667 | | - friend constexpr auto operator-(T) noexcept -> constant_wrapper<(-T::value)> { return {}; } |
| 668 | + friend constexpr auto operator-(T) noexcept -> constant_wrapper<(-T::value)> |
| 669 | + { return {}; } |
668 | 670 | template<@\exposid{constexpr-param}@ T> |
669 | | - friend constexpr auto operator~(T) noexcept -> constant_wrapper<(~T::value)> { return {}; } |
| 671 | + friend constexpr auto operator~(T) noexcept -> constant_wrapper<(~T::value)> |
| 672 | + { return {}; } |
670 | 673 | template<@\exposid{constexpr-param}@ T> |
671 | | - friend constexpr auto operator!(T) noexcept -> constant_wrapper<(!T::value)> { return {}; } |
| 674 | + friend constexpr auto operator!(T) noexcept -> constant_wrapper<(!T::value)> |
| 675 | + { return {}; } |
672 | 676 | template<@\exposid{constexpr-param}@ T> |
673 | | - friend constexpr auto operator&(T) noexcept -> constant_wrapper<(&T::value)> { return {}; } |
| 677 | + friend constexpr auto operator&(T) noexcept -> constant_wrapper<(&T::value)> |
| 678 | + { return {}; } |
674 | 679 | template<@\exposid{constexpr-param}@ T> |
675 | | - friend constexpr auto operator*(T) noexcept -> constant_wrapper<(*T::value)> { return {}; } |
| 680 | + friend constexpr auto operator*(T) noexcept -> constant_wrapper<(*T::value)> |
| 681 | + { return {}; } |
676 | 682 |
|
677 | 683 | // binary operators |
678 | 684 | template<@\exposid{constexpr-param}@ L, @\exposid{constexpr-param}@ R> |
679 | | - friend constexpr auto operator+(L, R) noexcept -> constant_wrapper<(L::value + R::value)> { return {}; } |
| 685 | + friend constexpr auto operator+(L, R) noexcept -> constant_wrapper<(L::value + R::value)> |
| 686 | + { return {}; } |
680 | 687 | template<@\exposid{constexpr-param}@ L, @\exposid{constexpr-param}@ R> |
681 | | - friend constexpr auto operator-(L, R) noexcept -> constant_wrapper<(L::value - R::value)> { return {}; } |
| 688 | + friend constexpr auto operator-(L, R) noexcept -> constant_wrapper<(L::value - R::value)> |
| 689 | + { return {}; } |
682 | 690 | template<@\exposid{constexpr-param}@ L, @\exposid{constexpr-param}@ R> |
683 | | - friend constexpr auto operator*(L, R) noexcept -> constant_wrapper<(L::value * R::value)> { return {}; } |
| 691 | + friend constexpr auto operator*(L, R) noexcept -> constant_wrapper<(L::value * R::value)> |
| 692 | + { return {}; } |
684 | 693 | template<@\exposid{constexpr-param}@ L, @\exposid{constexpr-param}@ R> |
685 | | - friend constexpr auto operator/(L, R) noexcept -> constant_wrapper<(L::value / R::value)> { return {}; } |
| 694 | + friend constexpr auto operator/(L, R) noexcept -> constant_wrapper<(L::value / R::value)> |
| 695 | + { return {}; } |
686 | 696 | template<@\exposid{constexpr-param}@ L, @\exposid{constexpr-param}@ R> |
687 | | - friend constexpr auto operator%(L, R) noexcept -> constant_wrapper<(L::value % R::value)> { return {}; } |
| 697 | + friend constexpr auto operator%(L, R) noexcept -> constant_wrapper<(L::value % R::value)> |
| 698 | + { return {}; } |
688 | 699 |
|
689 | 700 | template<@\exposid{constexpr-param}@ L, @\exposid{constexpr-param}@ R> |
690 | | - friend constexpr auto operator<<(L, R) noexcept -> constant_wrapper<(L::value << R::value)> { return {}; } |
| 701 | + friend constexpr auto operator<<(L, R) noexcept -> constant_wrapper<(L::value << R::value)> |
| 702 | + { return {}; } |
691 | 703 | template<@\exposid{constexpr-param}@ L, @\exposid{constexpr-param}@ R> |
692 | | - friend constexpr auto operator>>(L, R) noexcept -> constant_wrapper<(L::value >> R::value)> { return {}; } |
| 704 | + friend constexpr auto operator>>(L, R) noexcept -> constant_wrapper<(L::value >> R::value)> |
| 705 | + { return {}; } |
693 | 706 | template<@\exposid{constexpr-param}@ L, @\exposid{constexpr-param}@ R> |
694 | | - friend constexpr auto operator&(L, R) noexcept -> constant_wrapper<(L::value & R::value)> { return {}; } |
| 707 | + friend constexpr auto operator&(L, R) noexcept -> constant_wrapper<(L::value & R::value)> |
| 708 | + { return {}; } |
695 | 709 | template<@\exposid{constexpr-param}@ L, @\exposid{constexpr-param}@ R> |
696 | | - friend constexpr auto operator|(L, R) noexcept -> constant_wrapper<(L::value | R::value)> { return {}; } |
| 710 | + friend constexpr auto operator|(L, R) noexcept -> constant_wrapper<(L::value | R::value)> |
| 711 | + { return {}; } |
697 | 712 | template<@\exposid{constexpr-param}@ L, @\exposid{constexpr-param}@ R> |
698 | | - friend constexpr auto operator^(L, R) noexcept -> constant_wrapper<(L::value ^ R::value)> { return {}; } |
| 713 | + friend constexpr auto operator^(L, R) noexcept -> constant_wrapper<(L::value ^ R::value)> |
| 714 | + { return {}; } |
699 | 715 |
|
700 | 716 | template<@\exposid{constexpr-param}@ L, @\exposid{constexpr-param}@ R> |
701 | | - requires (!is_constructible_v<bool, decltype(L::value)> || !is_constructible_v<bool, decltype(R::value)>) |
702 | | - friend constexpr auto operator&&(L, R) noexcept -> constant_wrapper<(L::value && R::value)> { return {}; } |
| 717 | + requires (!is_constructible_v<bool, decltype(L::value)> || |
| 718 | + !is_constructible_v<bool, decltype(R::value)>) |
| 719 | + friend constexpr auto operator&&(L, R) noexcept -> constant_wrapper<(L::value && R::value)> |
| 720 | + { return {}; } |
703 | 721 | template<@\exposid{constexpr-param}@ L, @\exposid{constexpr-param}@ R> |
704 | | - requires (!is_constructible_v<bool, decltype(L::value)> || !is_constructible_v<bool, decltype(R::value)>) |
705 | | - friend constexpr auto operator||(L, R) noexcept -> constant_wrapper<(L::value || R::value)> { return {}; } |
| 722 | + requires (!is_constructible_v<bool, decltype(L::value)> || |
| 723 | + !is_constructible_v<bool, decltype(R::value)>) |
| 724 | + friend constexpr auto operator||(L, R) noexcept -> constant_wrapper<(L::value || R::value)> |
| 725 | + { return {}; } |
706 | 726 |
|
707 | 727 | // comparisons |
708 | 728 | template<@\exposid{constexpr-param}@ L, @\exposid{constexpr-param}@ R> |
709 | | - friend constexpr auto operator<=>(L, R) noexcept -> constant_wrapper<(L::value <=> R::value)> { return {}; } |
| 729 | + friend constexpr auto operator<=>(L, R) noexcept -> constant_wrapper<(L::value <=> R::value)> |
| 730 | + { return {}; } |
710 | 731 | template<@\exposid{constexpr-param}@ L, @\exposid{constexpr-param}@ R> |
711 | | - friend constexpr auto operator<(L, R) noexcept -> constant_wrapper<(L::value < R::value)> { return {}; } |
| 732 | + friend constexpr auto operator<(L, R) noexcept -> constant_wrapper<(L::value < R::value)> |
| 733 | + { return {}; } |
712 | 734 | template<@\exposid{constexpr-param}@ L, @\exposid{constexpr-param}@ R> |
713 | | - friend constexpr auto operator<=(L, R) noexcept -> constant_wrapper<(L::value <= R::value)> { return {}; } |
| 735 | + friend constexpr auto operator<=(L, R) noexcept -> constant_wrapper<(L::value <= R::value)> |
| 736 | + { return {}; } |
714 | 737 | template<@\exposid{constexpr-param}@ L, @\exposid{constexpr-param}@ R> |
715 | | - friend constexpr auto operator==(L, R) noexcept -> constant_wrapper<(L::value == R::value)> { return {}; } |
| 738 | + friend constexpr auto operator==(L, R) noexcept -> constant_wrapper<(L::value == R::value)> |
| 739 | + { return {}; } |
716 | 740 | template<@\exposid{constexpr-param}@ L, @\exposid{constexpr-param}@ R> |
717 | | - friend constexpr auto operator!=(L, R) noexcept -> constant_wrapper<(L::value != R::value)> { return {}; } |
| 741 | + friend constexpr auto operator!=(L, R) noexcept -> constant_wrapper<(L::value != R::value)> |
| 742 | + { return {}; } |
718 | 743 | template<@\exposid{constexpr-param}@ L, @\exposid{constexpr-param}@ R> |
719 | | - friend constexpr auto operator>(L, R) noexcept -> constant_wrapper<(L::value > R::value)> { return {}; } |
| 744 | + friend constexpr auto operator>(L, R) noexcept -> constant_wrapper<(L::value > R::value)> |
| 745 | + { return {}; } |
720 | 746 | template<@\exposid{constexpr-param}@ L, @\exposid{constexpr-param}@ R> |
721 | | - friend constexpr auto operator>=(L, R) noexcept -> constant_wrapper<(L::value >= R::value)> { return {}; } |
| 747 | + friend constexpr auto operator>=(L, R) noexcept -> constant_wrapper<(L::value >= R::value)> |
| 748 | + { return {}; } |
722 | 749 |
|
723 | 750 | template<@\exposid{constexpr-param}@ L, @\exposid{constexpr-param}@ R> |
724 | 751 | friend constexpr auto operator,(L, R) noexcept = delete; |
|
732 | 759 | requires requires(Args...) { constant_wrapper<T::value(Args::value...)>(); } |
733 | 760 | { return constant_wrapper<T::value(Args::value...)>{}; } |
734 | 761 | template<@\exposid{constexpr-param}@ T, @\exposid{constexpr-param}@... Args> |
735 | | - constexpr auto operator[](this T, Args...) noexcept -> constant_wrapper<(T::value[Args::value...])> |
736 | | - { return {}; } |
| 762 | + constexpr auto operator[](this T, Args...) noexcept |
| 763 | + -> constant_wrapper<(T::value[Args::value...])> |
| 764 | + { return {}; } |
737 | 765 |
|
738 | 766 | // pseudo-mutators |
739 | 767 | template<@\exposid{constexpr-param}@ T> |
740 | | - constexpr auto operator++(this T) noexcept requires requires(T::value_type x) { ++x; } |
741 | | - { return constant_wrapper<[] { auto c = T::value; return ++c; }()>{}; } |
| 768 | + constexpr auto operator++(this T) noexcept |
| 769 | + requires requires(T::value_type x) { ++x; } |
| 770 | + { return constant_wrapper<[] { auto c = T::value; return ++c; }()>{}; } |
742 | 771 | template<@\exposid{constexpr-param}@ T> |
743 | | - constexpr auto operator++(this T, int) noexcept requires requires(T::value_type x) { x++; } |
744 | | - { return constant_wrapper<[] { auto c = T::value; return c++; }()>{}; } |
| 772 | + constexpr auto operator++(this T, int) noexcept |
| 773 | + requires requires(T::value_type x) { x++; } |
| 774 | + { return constant_wrapper<[] { auto c = T::value; return c++; }()>{}; } |
745 | 775 |
|
746 | 776 | template<@\exposid{constexpr-param}@ T> |
747 | | - constexpr auto operator--(this T) noexcept requires requires(T::value_type x) { --x; } |
748 | | - { return constant_wrapper<[] { auto c = T::value; return --c; }()>{}; } |
| 777 | + constexpr auto operator--(this T) noexcept |
| 778 | + requires requires(T::value_type x) { --x; } |
| 779 | + { return constant_wrapper<[] { auto c = T::value; return --c; }()>{}; } |
749 | 780 | template<@\exposid{constexpr-param}@ T> |
750 | | - constexpr auto operator--(this T, int) noexcept requires requires(T::value_type x) { x--; } |
751 | | - { return constant_wrapper<[] { auto c = T::value; return c--; }()>{}; } |
| 781 | + constexpr auto operator--(this T, int) noexcept |
| 782 | + requires requires(T::value_type x) { x--; } |
| 783 | + { return constant_wrapper<[] { auto c = T::value; return c--; }()>{}; } |
752 | 784 |
|
753 | 785 | template<@\exposid{constexpr-param}@ T, @\exposid{constexpr-param}@ R> |
754 | | - constexpr auto operator+=(this T, R) noexcept requires requires(T::value_type x) { x += R::value; } |
755 | | - { return constant_wrapper<[] { auto v = T::value; return v += R::value; }()>{}; } |
| 786 | + constexpr auto operator+=(this T, R) noexcept |
| 787 | + requires requires(T::value_type x) { x += R::value; } |
| 788 | + { return constant_wrapper<[] { auto v = T::value; return v += R::value; }()>{}; } |
756 | 789 | template<@\exposid{constexpr-param}@ T, @\exposid{constexpr-param}@ R> |
757 | | - constexpr auto operator-=(this T, R) noexcept requires requires(T::value_type x) { x -= R::value; } |
758 | | - { return constant_wrapper<[] { auto v = T::value; return v -= R::value; }()>{}; } |
| 790 | + constexpr auto operator-=(this T, R) noexcept |
| 791 | + requires requires(T::value_type x) { x -= R::value; } |
| 792 | + { return constant_wrapper<[] { auto v = T::value; return v -= R::value; }()>{}; } |
759 | 793 | template<@\exposid{constexpr-param}@ T, @\exposid{constexpr-param}@ R> |
760 | | - constexpr auto operator*=(this T, R) noexcept requires requires(T::value_type x) { x *= R::value; } |
761 | | - { return constant_wrapper<[] { auto v = T::value; return v *= R::value; }()>{}; } |
| 794 | + constexpr auto operator*=(this T, R) noexcept |
| 795 | + requires requires(T::value_type x) { x *= R::value; } |
| 796 | + { return constant_wrapper<[] { auto v = T::value; return v *= R::value; }()>{}; } |
762 | 797 | template<@\exposid{constexpr-param}@ T, @\exposid{constexpr-param}@ R> |
763 | | - constexpr auto operator/=(this T, R) noexcept requires requires(T::value_type x) { x /= R::value; } |
764 | | - { return constant_wrapper<[] { auto v = T::value; return v /= R::value; }()>{}; } |
| 798 | + constexpr auto operator/=(this T, R) noexcept |
| 799 | + requires requires(T::value_type x) { x /= R::value; } |
| 800 | + { return constant_wrapper<[] { auto v = T::value; return v /= R::value; }()>{}; } |
765 | 801 | template<@\exposid{constexpr-param}@ T, @\exposid{constexpr-param}@ R> |
766 | | - constexpr auto operator%=(this T, R) noexcept requires requires(T::value_type x) { x %= R::value; } |
767 | | - { return constant_wrapper<[] { auto v = T::value; return v %= R::value; }()>{}; } |
| 802 | + constexpr auto operator%=(this T, R) noexcept |
| 803 | + requires requires(T::value_type x) { x %= R::value; } |
| 804 | + { return constant_wrapper<[] { auto v = T::value; return v %= R::value; }()>{}; } |
768 | 805 | template<@\exposid{constexpr-param}@ T, @\exposid{constexpr-param}@ R> |
769 | | - constexpr auto operator&=(this T, R) noexcept requires requires(T::value_type x) { x &= R::value; } |
770 | | - { return constant_wrapper<[] { auto v = T::value; return v &= R::value; }()>{}; } |
| 806 | + constexpr auto operator&=(this T, R) noexcept |
| 807 | + requires requires(T::value_type x) { x &= R::value; } |
| 808 | + { return constant_wrapper<[] { auto v = T::value; return v &= R::value; }()>{}; } |
771 | 809 | template<@\exposid{constexpr-param}@ T, @\exposid{constexpr-param}@ R> |
772 | | - constexpr auto operator|=(this T, R) noexcept requires requires(T::value_type x) { x |= R::value; } |
773 | | - { return constant_wrapper<[] { auto v = T::value; return v |= R::value; }()>{}; } |
| 810 | + constexpr auto operator|=(this T, R) noexcept |
| 811 | + requires requires(T::value_type x) { x |= R::value; } |
| 812 | + { return constant_wrapper<[] { auto v = T::value; return v |= R::value; }()>{}; } |
774 | 813 | template<@\exposid{constexpr-param}@ T, @\exposid{constexpr-param}@ R> |
775 | | - constexpr auto operator^=(this T, R) noexcept requires requires(T::value_type x) { x ^= R::value; } |
776 | | - { return constant_wrapper<[] { auto v = T::value; return v ^= R::value; }()>{}; } |
| 814 | + constexpr auto operator^=(this T, R) noexcept |
| 815 | + requires requires(T::value_type x) { x ^= R::value; } |
| 816 | + { return constant_wrapper<[] { auto v = T::value; return v ^= R::value; }()>{}; } |
777 | 817 | template<@\exposid{constexpr-param}@ T, @\exposid{constexpr-param}@ R> |
778 | | - constexpr auto operator<<=(this T, R) noexcept requires requires(T::value_type x) { x <<= R::value; } |
779 | | - { return constant_wrapper<[] { auto v = T::value; return v <<= R::value; }()>{}; } |
| 818 | + constexpr auto operator<<=(this T, R) noexcept |
| 819 | + requires requires(T::value_type x) { x <<= R::value; } |
| 820 | + { return constant_wrapper<[] { auto v = T::value; return v <<= R::value; }()>{}; } |
780 | 821 | template<@\exposid{constexpr-param}@ T, @\exposid{constexpr-param}@ R> |
781 | | - constexpr auto operator>>=(this T, R) noexcept requires requires(T::value_type x) { x >>= R::value; } |
782 | | - { return constant_wrapper<[] { auto v = T::value; return v >>= R::value; }()>{}; } |
| 822 | + constexpr auto operator>>=(this T, R) noexcept |
| 823 | + requires requires(T::value_type x) { x >>= R::value; } |
| 824 | + { return constant_wrapper<[] { auto v = T::value; return v >>= R::value; }()>{}; } |
783 | 825 | }; |
784 | 826 |
|
785 | | -template<cw-fixed-value X, class> |
| 827 | +template<@\exposid{cw-fixed-value}@ X, class> |
786 | 828 | struct constant_wrapper: cw-operators { |
787 | 829 | static constexpr const auto & value = X.data; |
788 | 830 | using type = constant_wrapper; |
789 | 831 | using value_type = typename decltype(X)::type; |
790 | 832 |
|
791 | 833 | template<@\exposid{constexpr-param}@ R> |
792 | | - constexpr auto operator=(R) const noexcept requires requires(value_type x) { x = R::value; } |
793 | | - { return constant_wrapper<[] { auto v = value; return v = R::value; }()>{}; } |
| 834 | + constexpr auto operator=(R) const noexcept |
| 835 | + requires requires(value_type x) { x = R::value; } |
| 836 | + { return constant_wrapper<[] { auto v = value; return v = R::value; }()>{}; } |
794 | 837 |
|
795 | 838 | constexpr operator decltype(auto)() const noexcept { return value; } |
796 | 839 | }; |
|
838 | 881 | void deeply_flawed_underground_planning() { |
839 | 882 | constexpr auto gathered_quantity = middle_phase(initial_phase(42, 13)); |
840 | 883 | constexpr auto all_available = 55; |
841 | | - final_phase(gathered_quantity, all_available); // error: `gathered == available' is not a constant expression |
| 884 | + final_phase(gathered_quantity, all_available); // error: |
| 885 | + // `gathered == available' is not a constant expression |
842 | 886 | } |
843 | 887 | \end{codeblock} |
844 | 888 | \end{example} |
|
0 commit comments