// in Fortran.
#include "../../runtime/character.h"
+#include "../../runtime/descriptor.h"
#include "gtest/gtest.h"
#include <cstring>
#include <functional>
std::memcpy(buf[0], x, xBytes);
std::memcpy(buf[1], y, yBytes);
ASSERT_EQ(cmp, expect) << "compare '" << x << "'(" << xBytes << ") to '"
- << y << "'(" << yBytes << "), got " << cmp
+ << y << "'(" << yBytes << "'), got " << cmp
<< ", should be " << expect << '\n';
}
}
+// Test MIN() and MAX()
+struct ExtremumTestCase {
+ const char *x, *y, *expect;
+};
+
+template <typename CHAR>
+void RunExtremumTests(const char *which,
+ std::function<void(Descriptor &, const Descriptor &, const char *, int)>
+ function,
+ const std::vector<ExtremumTestCase> &testCases) {
+
+ // Helper for creating, allocating and filling up a descriptor with data from
+ // a raw character literal, converted to the CHAR type used by the test.
+ auto CreateDescriptor = [](const char *raw) -> OwningPtr<Descriptor> {
+ std::size_t length{std::strlen(raw)};
+ std::basic_string<CHAR> converted{raw, raw + length};
+
+ OwningPtr<Descriptor> descriptor{Descriptor::Create(
+ sizeof(CHAR), length, nullptr, 0, nullptr, CFI_attribute_allocatable)};
+ if (descriptor->Allocate() != 0) {
+ return nullptr;
+ }
+
+ std::copy(
+ converted.begin(), converted.end(), descriptor->OffsetElement<CHAR>());
+
+ return descriptor;
+ };
+
+ for (const auto &t : testCases) {
+ OwningPtr<Descriptor> x = CreateDescriptor(t.x);
+ OwningPtr<Descriptor> y = CreateDescriptor(t.y);
+
+ ASSERT_NE(x, nullptr);
+ ASSERT_TRUE(x->IsAllocated());
+ ASSERT_NE(y, nullptr);
+ ASSERT_TRUE(y->IsAllocated());
+ function(*x, *y, nullptr, 0);
+
+ std::basic_string<CHAR> got{
+ x->OffsetElement<CHAR>(), x->ElementBytes() / sizeof(CHAR)};
+ std::basic_string<CHAR> expect{t.expect, t.expect + std::strlen(t.expect)};
+ EXPECT_EQ(expect, got) << which << "('" << t.x << "','" << t.y
+ << "') for CHARACTER(kind=" << sizeof(CHAR) << ")";
+ }
+}
+
+template <typename CHAR> struct ExtremumTests : public ::testing::Test {};
+TYPED_TEST_CASE(ExtremumTests, CharacterTypes);
+
+TYPED_TEST(ExtremumTests, MinTests) {
+ static std::vector<ExtremumTestCase> tests{
+ {"a", "z", "a"},
+ {"zaaa", "aa", "aa "},
+ {"aaz", "aaaaa", "aaaaa"},
+ };
+ RunExtremumTests<TypeParam>("MIN", RTNAME(CharacterMin), tests);
+}
+
+TYPED_TEST(ExtremumTests, MaxTests) {
+ static std::vector<ExtremumTestCase> tests{
+ {"a", "z", "z"},
+ {"zaa", "aaaaa", "zaa "},
+ {"aaaaa", "aazaa", "aazaa"},
+ };
+ RunExtremumTests<TypeParam>("MAX", RTNAME(CharacterMax), tests);
+}
+
// Test search functions INDEX(), SCAN(), and VERIFY()
template <typename CHAR>