// std::vector<std::optional<A>> -> std::optional<std::vector<A>>
// i.e., inverts a vector of optional values into an optional vector that
-// has a value of if all of the original elements were present.
+// will have a value only when all of the original elements are present.
template<typename A>
std::optional<std::vector<A>> AllElementsPresent(
std::vector<std::optional<A>> &&v) {
Substring FoldOperation(FoldingContext &, Substring &&);
ComplexPart FoldOperation(FoldingContext &, ComplexPart &&);
template<int KIND>
-Expr<Type<TypeCategory::Integer, KIND>> FoldOperation(FoldingContext &context,
- FunctionRef<Type<TypeCategory::Integer, KIND>> &&funcRef);
+Expr<Type<TypeCategory::Integer, KIND>> FoldOperation(
+ FoldingContext &context, FunctionRef<Type<TypeCategory::Integer, KIND>> &&);
+template<int KIND>
+Expr<Type<TypeCategory::Real, KIND>> FoldOperation(
+ FoldingContext &context, FunctionRef<Type<TypeCategory::Real, KIND>> &&);
+template<int KIND>
+Expr<Type<TypeCategory::Complex, KIND>> FoldOperation(
+ FoldingContext &context, FunctionRef<Type<TypeCategory::Complex, KIND>> &&);
+// TODO: Character intrinsic function folding
+template<int KIND>
+Expr<Type<TypeCategory::Logical, KIND>> FoldOperation(
+ FoldingContext &context, FunctionRef<Type<TypeCategory::Logical, KIND>> &&);
template<typename T> Expr<T> FoldOperation(FoldingContext &, Designator<T> &&);
template<int KIND>
Expr<Type<TypeCategory::Integer, KIND>> FoldOperation(
[&](auto &kindExpr) -> Expr<TO> {
kindExpr = Fold(context, std::move(kindExpr));
using Operand = ResultType<decltype(kindExpr)>;
+ // TODO pmk: conversion of array constructors (constant or not)
char buffer[64];
if (auto value{GetScalarConstantValue<Operand>(kindExpr)}) {
if constexpr (TO::category == TypeCategory::Integer) {
ExtentExpr{call.arguments().front().value().value().Rank()}}};
} else if (intrinsic->name == "reshape") {
if (call.arguments().size() >= 2 && call.arguments().at(1).has_value()) {
+ // SHAPE(RESHAPE(array,shape)) -> shape
+ const Expr<SomeType> &shapeExpr{call.arguments().at(1)->value()};
+ Expr<SomeInteger> shape{std::get<Expr<SomeInteger>>(shapeExpr.u)};
+ return AsShape(ConvertToType<ExtentType>(std::move(shape)));
}
} else {
// TODO: shapes of other non-elemental intrinsic results
integer(8), parameter :: ac3bs(:) = shape([(1,j=4,1,-1)])
integer(8), parameter :: ac4s(:) = shape([((j,k,j*k,k=1,3),j=1,4)])
integer(8), parameter :: ac5s(:) = shape([((0,k=5,1,-2),j=9,2,-3)])
+ integer(8), parameter :: rss(:) = shape(reshape([(0,j=1,90)], [10_8,9_8]))
contains
subroutine subr(x,n1,n2)
real, intent(in) :: x(:,:)
! integer(8),parameter::ac3bs(1_8:)=[Integer(8)::4_8]
! integer(8),parameter::ac4s(1_8:)=[Integer(8)::36_8]
! integer(8),parameter::ac5s(1_8:)=[Integer(8)::9_8]
+! integer(8),parameter::rss(1_8:)=[Integer(8)::10_8,9_8]
! contains
! subroutine subr(x,n1,n2)
! real(4),intent(in)::x(1_8:,1_8:)