@@ -42,118 +42,124 @@ template <class SF>
4242struct RandomAccessAt {
4343 MemLayout::size_t i;
4444 template <class ... Args>
45- constexpr SF operator ()(Args& ...args) const { return {args[i]...}; }
45+ [[gnu::always_inline]] constexpr SF operator ()(Args& ...args) const { return {args[i]...}; }
4646 template <class ... Args>
47- constexpr SF operator ()(const Args& ...args) const { return {args[i]...}; }
47+ [[gnu::always_inline]] constexpr SF operator ()(const Args& ...args) const { return {args[i]...}; }
4848};
4949
5050template <class SF >
5151struct GetPointer {
5252 template <class ... Args>
53- constexpr SF operator ()(Args& ...args) const { return {&args...}; }
53+ [[gnu::always_inline]] constexpr SF operator ()(Args& ...args) const { return {&args...}; }
5454 template <class ... Args>
55- constexpr SF operator ()(const Args& ...args) const { return {&args...}; }
55+ [[gnu::always_inline]] constexpr SF operator ()(const Args& ...args) const { return {&args...}; }
5656};
5757
5858template <class SF >
5959struct AggregateConstructor {
6060 template <class ... Args>
61- constexpr SF operator ()(Args& ...args) const { return {args...}; }
61+ [[gnu::always_inline]] constexpr SF operator ()(Args& ...args) const { return {args...}; }
6262 template <class ... Args>
63- constexpr SF operator ()(const Args& ...args) const { return {args...}; }
63+ [[gnu::always_inline]] constexpr SF operator ()(const Args& ...args) const { return {args...}; }
6464};
6565
6666template <class SF >
6767struct PreIncrement {
6868 template <class ... Args>
69- constexpr SF operator ()(Args& ...args) const { return {++args...}; }
69+ [[gnu::always_inline]] constexpr SF operator ()(Args& ...args) const { return {++args...}; }
7070};
7171
7272template <class SF >
7373struct PreDecrement {
7474 template <class ... Args>
75- constexpr SF operator ()(Args& ...args) const { return {--args...}; }
75+ [[gnu::always_inline]] constexpr SF operator ()(Args& ...args) const { return {--args...}; }
7676};
7777
7878template <class SF >
7979struct Advance {
8080 ptrdiff_t i;
8181 template <class ... Args>
82- constexpr SF operator ()(const Args& ...args) const { return {(args + i)...}; }
82+ [[gnu::always_inline]] constexpr SF operator ()(const Args& ...args) const { return {(args + i)...}; }
8383};
8484
8585struct CopyAssignment {
8686 template <class Left , class Right >
87- constexpr Left& operator ()(Left& left, const Right& right) const { return left = right; }
87+ [[gnu::always_inline]] constexpr Left& operator ()(Left& left, const Right& right) const { return left = right; }
8888};
8989
9090// ////////////// apply to members methods
9191
92- template < class Self , class FunctionObject >
93- constexpr auto apply_unary (Self &self, FunctionObject&& f) {
94- auto construct_output = [&]< size_t ... Is>( std::index_sequence<Is...>) {
92+ struct apply_unary_helper {
93+ template < class Self , class FunctionObject , size_t ... Is>
94+ [[gnu::always_inline]] constexpr auto operator ()(Self& self, FunctionObject&& f, std::index_sequence<Is...>) const {
9595 return f (self.[:nsdms (^^Self)[Is]:]...);
96- };
96+ }
97+ };
98+
99+ template <class Self , class FunctionObject >
100+ [[gnu::always_inline]] constexpr auto apply_unary (Self &self, FunctionObject&& f) {
97101 constexpr auto indices = std::make_index_sequence<count_members<Self>()>{};
98- return construct_output ( indices);
102+ return apply_unary_helper{}(self, std::forward<FunctionObject>(f), indices);
99103}
100104
101105// apply on skeleton struct S<F>
102106template <class FunctionObject , template <template <class > class > class S , template <class > class F >
103- constexpr auto apply (S<F> &self, FunctionObject&& f) {
107+ [[gnu::always_inline]] constexpr auto apply (S<F> &self, FunctionObject&& f) {
104108 return apply_unary (self, std::forward<FunctionObject&&>(f));
105109}
106110
107111template <class FunctionObject , template <template <class > class > class S , template <class > class F >
108- constexpr auto apply (const S<F> &self, FunctionObject&& f) {
112+ [[gnu::always_inline]] constexpr auto apply (const S<F> &self, FunctionObject&& f) {
109113 return apply_unary (self, std::forward<FunctionObject&&>(f));
110114}
111115
112116// apply on wrappers, forwarding to the base type
113117template <class FunctionObject , class Self >
114118 requires requires { typename Self::Base; }
115- constexpr auto apply (Self &self, FunctionObject&& f) {
119+ [[gnu::always_inline]] constexpr auto apply (Self &self, FunctionObject&& f) {
116120 return apply_unary<typename Self::Base>(self, std::forward<FunctionObject&&>(f));
117121}
118122
119123template <class FunctionObject , class Self >
120124 requires requires { typename Self::Base; }
121- constexpr auto apply (const Self &self, FunctionObject&& f) {
125+ [[gnu::always_inline]] constexpr auto apply (const Self &self, FunctionObject&& f) {
122126 return apply_unary<const typename Self::Base>(self, std::forward<FunctionObject&&>(f));
123127}
124128
129+ struct apply_binary_helper {
130+ template <class Self , class Other , class FunctionObject , size_t ... Is>
131+ [[gnu::always_inline]] constexpr Self operator ()(Self& self, Other& other, FunctionObject&& f, std::index_sequence<Is...>) const {
132+ return {f (self.[:nsdms (^^Self)[Is]:], other.[:nsdms (^^Other)[Is]:])...};
133+ }
134+ };
125135
126136// template <class FunctionObject, class Self, class Other>
127137// constexpr auto apply(Self &self, Other &other, FunctionObject&& f) {
128138template <class Self , class Other , class FunctionObject >
129- constexpr auto apply_binary (Self &self, Other &other, FunctionObject&& f) {
130- auto construct_output = [&]<size_t ... Is>(std::index_sequence<Is...>) -> Self {
131- return {f (
132- self.[:nsdms (^^Self)[Is]:], other.[:nsdms (^^Other)[Is]:])...};
133- };
139+ [[gnu::always_inline]] constexpr auto apply_binary (Self &self, Other &other, FunctionObject&& f) {
134140 constexpr auto indices = std::make_index_sequence<count_members<Self>()>{};
135- return construct_output ( indices);
141+ return apply_binary_helper{}(self, other, std::forward<FunctionObject&&>(f), indices);
136142}
137143
138144template <class FunctionObject , template <template <class > class > class S , template <class > class F_self , template <class > class F_other >
139- constexpr auto apply (S<F_self> &self, S<F_other> &other, FunctionObject&& f) {
145+ [[gnu::always_inline]] constexpr auto apply (S<F_self> &self, S<F_other> &other, FunctionObject&& f) {
140146 return apply_binary (self, other, std::forward<FunctionObject&&>(f));
141147}
142148
143149template <class FunctionObject , template <template <class > class > class S , template <class > class F_self , template <class > class F_other >
144- constexpr auto apply (S<F_self> &self, const S<F_other> &other, FunctionObject&& f) {
150+ [[gnu::always_inline]] constexpr auto apply (S<F_self> &self, const S<F_other> &other, FunctionObject&& f) {
145151 return apply_binary (self, other, std::forward<FunctionObject&&>(f));
146152}
147153
148154template <class Self , class Other , class FunctionObject >
149155 requires requires { typename Self::Base; typename Other::Base; }
150- constexpr auto apply (Self &self, Other &other, FunctionObject&& f) {
156+ [[gnu::always_inline]] constexpr auto apply (Self &self, Other &other, FunctionObject&& f) {
151157 return apply_binary<typename Self::Base, typename Other::Base>(self, other, std::forward<FunctionObject&&>(f));
152158}
153159
154160template <class Self , class Other , class FunctionObject >
155161 requires requires { typename Self::Base; typename Other::Base; }
156- constexpr auto apply (Self &self, const Other &other, FunctionObject&& f) {
162+ [[gnu::always_inline]] constexpr auto apply (Self &self, const Other &other, FunctionObject&& f) {
157163 static_assert (count_members<typename Self::Base>() == 4 );
158164 return apply_binary<typename Self::Base, const typename Other::Base>(self, other, std::forward<FunctionObject&&>(f));
159165}
@@ -174,13 +180,13 @@ struct wrapper : public S<F> {
174180 template <template <class > class F_other >
175181 constexpr wrapper (const S<F_other>& other) : Base{apply (other, AggregateConstructor<Base>{})} {}
176182
177- constexpr wrapper<S, reference> operator [] (size_t i) {
183+ [[gnu::always_inline]] constexpr wrapper<S, reference> operator [] (size_t i) {
178184 return apply (*this , RandomAccessAt<S<reference>>{i}); }
179- constexpr wrapper<S, const_reference> operator [] (size_t i) const {
185+ [[gnu::always_inline]] constexpr wrapper<S, const_reference> operator [] (size_t i) const {
180186 return apply (*this , RandomAccessAt<S<const_reference>>{i}); }
181187
182- constexpr wrapper<S, reference> operator *() { return operator [](0 ); }
183- constexpr wrapper<S, const_reference> operator *(ptrdiff_t ) const { return operator [](0 ); }
188+ [[gnu::always_inline]] constexpr wrapper<S, reference> operator *() { return operator [](0 ); }
189+ [[gnu::always_inline]] constexpr wrapper<S, const_reference> operator *(ptrdiff_t ) const { return operator [](0 ); }
184190};
185191
186192template <template <template <class > class > class S >
@@ -315,15 +321,15 @@ struct wrapper<S, pointer> : public S<pointer> {
315321 constexpr wrapper () = default;
316322 constexpr wrapper (Base b) : Base{static_cast <Base&&>(b)} {}
317323
318- constexpr wrapper<S, reference> operator [] (size_t i) {
324+ [[gnu::always_inline]] constexpr wrapper<S, reference> operator [] (size_t i) {
319325 return apply (*this , RandomAccessAt<S<reference>>{i}); }
320- constexpr const wrapper<S, const_reference> operator [] (size_t i) const {
326+ [[gnu::always_inline]] constexpr const wrapper<S, const_reference> operator [] (size_t i) const {
321327 return apply (*this , RandomAccessAt<S<const_reference>>{i}); }
322328
323- constexpr wrapper<S, reference> operator *() { return operator [](0 ); }
324- constexpr wrapper<S, const_reference> operator *() const { return operator [](0 ); }
325- constexpr wrapper<S, reference> operator ->() { return operator [](0 ); }
326- constexpr wrapper<S, const_reference> operator ->() const { return operator [](0 ); }
329+ [[gnu::always_inline]] constexpr wrapper<S, reference> operator *() { return operator [](0 ); }
330+ [[gnu::always_inline]] constexpr wrapper<S, const_reference> operator *() const { return operator [](0 ); }
331+ [[gnu::always_inline]] constexpr wrapper<S, reference> operator ->() { return operator [](0 ); }
332+ [[gnu::always_inline]] constexpr wrapper<S, const_reference> operator ->() const { return operator [](0 ); }
327333
328334 constexpr bool operator ==(const wrapper& other) const {
329335 return this ->[:nsdms (^^Base)[0 ]:] == other.[:nsdms (^^Base)[0 ]:]; }
@@ -357,16 +363,16 @@ struct wrapper<S, const_pointer> : public S<const_pointer> {
357363 constexpr wrapper (Base b) : Base{static_cast <Base&&>(b)} {}
358364 constexpr wrapper (const S<pointer>& other) : Base(apply(other, AggregateConstructor<Base>{})) {}
359365
360- constexpr wrapper<S, const_reference> operator [] (size_t i) const {
366+ [[gnu::always_inline]] constexpr wrapper<S, const_reference> operator [] (size_t i) const {
361367 return apply (*this , RandomAccessAt<S<const_reference>>{i}); }
362- constexpr wrapper<S, const_reference> operator *() const { return operator [](0 ); }
363- constexpr wrapper<S, const_reference> operator ->() const { return operator [](0 ); }
368+ [[gnu::always_inline]] constexpr wrapper<S, const_reference> operator *() const { return operator [](0 ); }
369+ [[gnu::always_inline]] constexpr wrapper<S, const_reference> operator ->() const { return operator [](0 ); }
364370
365- constexpr bool operator ==(const wrapper& other) const {
371+ [[gnu::always_inline]] constexpr bool operator ==(const wrapper& other) const {
366372 return this ->[:nsdms (^^Base)[0 ]:] == other.[:nsdms (^^Base)[0 ]:]; }
367- constexpr bool operator !=(const wrapper& other) const {
373+ [[gnu::always_inline]] constexpr bool operator !=(const wrapper& other) const {
368374 return !this ->operator ==(other); }
369- constexpr bool operator <(const wrapper& other) const {
375+ [[gnu::always_inline]] constexpr bool operator <(const wrapper& other) const {
370376 return this ->[:nsdms (^^Base)[0 ]:] < other.[:nsdms (^^Base)[0 ]:]; }
371377
372378 constexpr wrapper operator +(ptrdiff_t i) const {
0 commit comments