}
}
-} // extern "C" - TODO put Reshape under extern "C"
+// RESHAPE
// F2018 16.9.163
-OwningPtr<Descriptor> RTNAME(Reshape)(const Descriptor &source,
+void RTNAME(Reshape)(Descriptor &result, const Descriptor &source,
const Descriptor &shape, const Descriptor *pad, const Descriptor *order,
const char *sourceFile, int line) {
// Compute and check the rank of the result.
RUNTIME_CHECK(terminator, order->GetDimension(0).Extent() == resultRank);
std::uint64_t values{0};
SubscriptValue orderSubscript{order->GetDimension(0).LowerBound()};
+ std::size_t orderElementBytes{order->ElementBytes()};
for (SubscriptValue j{0}; j < resultRank; ++j, ++orderSubscript) {
- auto k{GetInt64(order->OffsetElement<char>(orderSubscript),
- shapeElementBytes, terminator)};
+ auto k{GetInt64(order->Element<char>(&orderSubscript), orderElementBytes,
+ terminator)};
RUNTIME_CHECK(
terminator, k >= 1 && k <= resultRank && !((values >> k) & 1));
values |= std::uint64_t{1} << k;
}
}
- // Create and populate the result's descriptor.
- const DescriptorAddendum *sourceAddendum{source.Addendum()};
- const typeInfo::DerivedType *sourceDerivedType{
- sourceAddendum ? sourceAddendum->derivedType() : nullptr};
- OwningPtr<Descriptor> result;
- if (sourceDerivedType) {
- result = Descriptor::Create(*sourceDerivedType, nullptr, resultRank,
- resultExtent, CFI_attribute_allocatable);
- } else {
- result = Descriptor::Create(source.type(), elementBytes, nullptr,
- resultRank, resultExtent,
- CFI_attribute_allocatable); // TODO rearrange these arguments
- }
- DescriptorAddendum *resultAddendum{result->Addendum()};
- RUNTIME_CHECK(terminator, resultAddendum);
- resultAddendum->flags() |= DescriptorAddendum::DoNotFinalize;
- if (sourceDerivedType) {
- std::size_t lenParameters{sourceAddendum->LenParameters()};
- for (std::size_t j{0}; j < lenParameters; ++j) {
- resultAddendum->SetLenParameterValue(
- j, sourceAddendum->LenParameterValue(j));
- }
- }
- // Allocate storage for the result's data.
- for (int j{0}; j < resultRank; ++j) {
- result->GetDimension(j).SetBounds(1, resultExtent[j]);
- }
- int status{result->Allocate()};
- if (status != CFI_SUCCESS) {
- terminator.Crash("RESHAPE: Allocate failed (error %d)", status);
- }
+ // Allocate result descriptor
+ AllocateResult(
+ result, source, resultRank, resultExtent, terminator, "RESHAPE");
// Populate the result's elements.
SubscriptValue resultSubscript[maxRank];
- result->GetLowerBounds(resultSubscript);
+ result.GetLowerBounds(resultSubscript);
SubscriptValue sourceSubscript[maxRank];
source.GetLowerBounds(sourceSubscript);
std::size_t resultElement{0};
std::size_t elementsFromSource{std::min(resultElements, sourceElements)};
for (; resultElement < elementsFromSource; ++resultElement) {
- CopyElement(*result, resultSubscript, source, sourceSubscript, terminator);
+ CopyElement(result, resultSubscript, source, sourceSubscript, terminator);
source.IncrementSubscripts(sourceSubscript);
- result->IncrementSubscripts(resultSubscript, dimOrder);
+ result.IncrementSubscripts(resultSubscript, dimOrder);
}
if (resultElement < resultElements) {
// Remaining elements come from the optional PAD= argument.
SubscriptValue padSubscript[maxRank];
pad->GetLowerBounds(padSubscript);
for (; resultElement < resultElements; ++resultElement) {
- CopyElement(*result, resultSubscript, *pad, padSubscript, terminator);
+ CopyElement(result, resultSubscript, *pad, padSubscript, terminator);
pad->IncrementSubscripts(padSubscript);
- result->IncrementSubscripts(resultSubscript, dimOrder);
+ result.IncrementSubscripts(resultSubscript, dimOrder);
}
}
-
- return result;
}
-extern "C" { // TODO - remove when Reshape is under extern "C"
// SPREAD
void RTNAME(Spread)(Descriptor &result, const Descriptor &source, int dim,
MATCH(2, pad.GetDimension(0).Extent());
MATCH(2, pad.GetDimension(1).Extent());
MATCH(3, pad.GetDimension(2).Extent());
+ StaticDescriptor<1> orderDescriptor;
+ Descriptor &order{orderDescriptor.descriptor()};
+ static const std::int32_t orderData[]{1, 2};
+ static const SubscriptValue orderExtent[]{2};
+ order.Establish(TypeCategory::Integer, static_cast<int>(sizeof orderData[0]),
+ const_cast<void *>(reinterpret_cast<const void *>(orderData)), 1,
+ orderExtent, CFI_attribute_pointer);
+ orderDescriptor.Check();
+ order.Check();
+ MATCH(1, order.rank());
+ MATCH(2, order.GetDimension(0).Extent());
- auto result{
- RTNAME(Reshape)(*source, *shape, &pad, nullptr, __FILE__, __LINE__)};
+ auto result{Descriptor::Create(TypeCategory::Integer, sizeof(std::int32_t),
+ nullptr, 2, nullptr, CFI_attribute_allocatable)};
TEST(result.get() != nullptr);
+ RTNAME(Reshape)(*result, *source, *shape, &pad, &order, __FILE__, __LINE__);
result->Check();
MATCH(sizeof(std::int32_t), result->ElementBytes());
MATCH(2, result->rank());
MATCH(j, *result->Element<std::int32_t>(ss));
}
- // TODO: test ORDER=
-
return testing::Complete();
}