@@ -64,6 +64,7 @@ template <typename T> class Folder {
64
64
65
65
Expr<T> CSHIFT (FunctionRef<T> &&);
66
66
Expr<T> EOSHIFT (FunctionRef<T> &&);
67
+ Expr<T> MERGE (FunctionRef<T> &&);
67
68
Expr<T> PACK (FunctionRef<T> &&);
68
69
Expr<T> RESHAPE (FunctionRef<T> &&);
69
70
Expr<T> SPREAD (FunctionRef<T> &&);
@@ -397,9 +398,11 @@ template <typename T> Expr<T> Folder<T>::Folding(Designator<T> &&designator) {
397
398
template <typename T>
398
399
Constant<T> *Folder<T>::Folding(std::optional<ActualArgument> &arg) {
399
400
if (auto *expr{UnwrapExpr<Expr<SomeType>>(arg)}) {
400
- if (!UnwrapExpr<Expr<T>>(*expr)) {
401
- if (auto converted{ConvertToType (T::GetType (), std::move (*expr))}) {
402
- *expr = Fold (context_, std::move (*converted));
401
+ if constexpr (T::category != TypeCategory::Derived) {
402
+ if (!UnwrapExpr<Expr<T>>(*expr)) {
403
+ if (auto converted{ConvertToType (T::GetType (), std::move (*expr))}) {
404
+ *expr = Fold (context_, std::move (*converted));
405
+ }
403
406
}
404
407
}
405
408
return UnwrapConstantValue<T>(*expr);
@@ -411,8 +414,6 @@ template <typename... A, std::size_t... I>
411
414
std::optional<std::tuple<const Constant<A> *...>> GetConstantArgumentsHelper (
412
415
FoldingContext &context, ActualArguments &arguments,
413
416
std::index_sequence<I...>) {
414
- static_assert (
415
- (... && IsSpecificIntrinsicType<A>)); // TODO derived types for MERGE?
416
417
static_assert (sizeof ...(A) > 0 );
417
418
std::tuple<const Constant<A> *...> args{
418
419
Folder<A>{context}.Folding (arguments.at (I))...};
@@ -489,7 +490,6 @@ Expr<TR> FoldElementalIntrinsicHelper(FoldingContext &context,
489
490
}
490
491
}
491
492
CHECK (rank == GetRank (shape));
492
-
493
493
// Compute all the scalar values of the results
494
494
std::vector<Scalar<TR>> results;
495
495
if (TotalElementCount (shape) > 0 ) {
@@ -513,6 +513,13 @@ Expr<TR> FoldElementalIntrinsicHelper(FoldingContext &context,
513
513
auto len{static_cast <ConstantSubscript>(
514
514
results.empty () ? 0 : results[0 ].length ())};
515
515
return Expr<TR>{Constant<TR>{len, std::move (results), std::move (shape)}};
516
+ } else if constexpr (TR::category == TypeCategory::Derived) {
517
+ if (!results.empty ()) {
518
+ return Expr<TR>{rank == 0
519
+ ? Constant<TR>{results.front ()}
520
+ : Constant<TR>{results.front ().derivedTypeSpec (),
521
+ std::move (results), std::move (shape)}};
522
+ }
516
523
} else {
517
524
return Expr<TR>{Constant<TR>{std::move (results), std::move (shape)}};
518
525
}
@@ -780,6 +787,16 @@ template <typename T> Expr<T> Folder<T>::EOSHIFT(FunctionRef<T> &&funcRef) {
780
787
return MakeInvalidIntrinsic (std::move (funcRef));
781
788
}
782
789
790
+ template <typename T> Expr<T> Folder<T>::MERGE(FunctionRef<T> &&funcRef) {
791
+ return FoldElementalIntrinsic<T, T, T, LogicalResult>(context_,
792
+ std::move (funcRef),
793
+ ScalarFunc<T, T, T, LogicalResult>(
794
+ [](const Scalar<T> &ifTrue, const Scalar<T> &ifFalse,
795
+ const Scalar<LogicalResult> &predicate) -> Scalar<T> {
796
+ return predicate.IsTrue () ? ifTrue : ifFalse;
797
+ }));
798
+ }
799
+
783
800
template <typename T> Expr<T> Folder<T>::PACK(FunctionRef<T> &&funcRef) {
784
801
auto args{funcRef.arguments ()};
785
802
CHECK (args.size () == 3 );
@@ -1126,6 +1143,8 @@ Expr<T> FoldOperation(FoldingContext &context, FunctionRef<T> &&funcRef) {
1126
1143
return Folder<T>{context}.CSHIFT (std::move (funcRef));
1127
1144
} else if (name == " eoshift" ) {
1128
1145
return Folder<T>{context}.EOSHIFT (std::move (funcRef));
1146
+ } else if (name == " merge" ) {
1147
+ return Folder<T>{context}.MERGE (std::move (funcRef));
1129
1148
} else if (name == " pack" ) {
1130
1149
return Folder<T>{context}.PACK (std::move (funcRef));
1131
1150
} else if (name == " reshape" ) {
@@ -1147,17 +1166,6 @@ Expr<T> FoldOperation(FoldingContext &context, FunctionRef<T> &&funcRef) {
1147
1166
return Expr<T>{std::move (funcRef)};
1148
1167
}
1149
1168
1150
- template <typename T>
1151
- Expr<T> FoldMerge (FoldingContext &context, FunctionRef<T> &&funcRef) {
1152
- return FoldElementalIntrinsic<T, T, T, LogicalResult>(context,
1153
- std::move (funcRef),
1154
- ScalarFunc<T, T, T, LogicalResult>(
1155
- [](const Scalar<T> &ifTrue, const Scalar<T> &ifFalse,
1156
- const Scalar<LogicalResult> &predicate) -> Scalar<T> {
1157
- return predicate.IsTrue () ? ifTrue : ifFalse;
1158
- }));
1159
- }
1160
-
1161
1169
Expr<ImpliedDoIndex::Result> FoldOperation (FoldingContext &, ImpliedDoIndex &&);
1162
1170
1163
1171
// Array constructor folding
0 commit comments