Skip to content

Commit

Permalink
Merge pull request #57 from njoy/feature/type-cleanup
Browse files Browse the repository at this point in the history
Feature/type cleanup
  • Loading branch information
whaeck authored Nov 4, 2021
2 parents 3ec3ec3 + 8354b1c commit 208d078
Show file tree
Hide file tree
Showing 13 changed files with 437 additions and 356 deletions.
34 changes: 23 additions & 11 deletions autogen/json2class.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -237,16 +237,18 @@ std::string escape(const std::string &str)
// for initialization, as with: m.type var{return value of this function}
std::string initializer(const InfoMetadata &m)
{
// Leave an empty (or all-whitespace) m.defaultValue as-is;
// this is the "no initializer" case
// Leave an empty or all-whitespace m.defaultValue as-is.
// This is the "no initializer" case.
if (allws(m.defaultValue))
return "";

// If of string type, add double quotes;
// we assume that the input does NOT have those already!
if (m.type == "std::string" ||
m.type == "UTF8Text" ||
m.type == "XMLName")
// If of string type, add double quotes.
// We assume that the input does NOT have the quotes already!
// Note: we may not need all of these, but the GNDS manual does describe
// several string-like types, so we might as well include them.
if (m.type == "XMLName" || m.type == "UTF8Text" ||
m.type == "printableText" || m.type == "quotedText" ||
m.type == "tdText" || m.type == "string" || m.type == "std::string")
return '"' + escape(m.defaultValue) + '"';

// Leave as-is;
Expand Down Expand Up @@ -2127,31 +2129,41 @@ void filePythonClass(const InfoSpecs &specs, const PerClass &per)
writer out(per.cppPython);

static const std::map<std::string,std::pair<std::string,std::string>> map = {
// ---------------------- ----------- -----------------
// In per.dataType or The A name to use
// in per.metadata's appropriate for the function
// valueType defaultValue C++ type that returns them
// ---------------------- ----------- -----------------

// Described in the GNDS manual
// Described in the GNDS manual.
// I'm not sure which of the several types that map to std::string can,
// or would, appear in any GNDS specifications in such a way that we'd
// need it here, but listing all "string-like" types shouldn't hurt.
{ "Integer32" , { "int" , "ints" } },
{ "UInteger32" , { "unsigned" , "uints" } },
{ "Float64" , { "double" , "doubles" } },
{ "XMLName" , { "std::string" , "strings" } },
{ "UTF8Text" , { "std::string" , "strings" } },
{ "printableText" , { "std::string" , "strings" } },
{ "quotedText" , { "std::string" , "strings" } },
{ "tdText" , { "std::string" , "strings" } },

// Our versions of the above
// Our versions of the above.
{ "int" , { "int" , "ints" } },
{ "unsigned" , { "unsigned" , "uints" } },
{ "double" , { "double" , "doubles" } },
{ "string" , { "std::string" , "strings" } },
{ "std::string" , { "std::string" , "strings" } },

// Allow other sensible things
// Allow other sensible things.
{ "char" , { "char" , "chars" } },
{ "signed char" , { "signed char" , "schars" } },
{ "short" , { "short" , "shorts" } },
{ "long" , { "long" , "longs" } },
{ "long long" , { "long long" , "longlongs" } },
{ "unsigned char" , { "unsigned char" , "uchars" } },
{ "unsigned short" , { "unsigned short" , "ushorts" } },
{ "unsigned int" , { "unsigned int" , "uints" } },
{ "unsigned int" , { "unsigned" , "uints" } },
{ "unsigned long" , { "unsigned long" , "ulongs" } },
{ "unsigned long long" , { "unsigned long long" , "ulonglongs" } },
{ "float" , { "float" , "floats" } },
Expand Down
13 changes: 2 additions & 11 deletions src/GNDStk/BodyText/src/assign.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,19 +53,10 @@ operator=(const std::vector<T> &vec)
// set the raw string to "", because it's no longer considered meaningful
rawstring = "";

// length, start
// length, start, valueType
length(vec.size());
start(0);

// valueType: best guess
if constexpr (std::is_same_v<T,Integer32>)
valueType("Integer32");
else if constexpr (std::is_same_v<T,Float64>)
valueType("Float64");
else if constexpr (std::is_same_v<T,UTF8Text>)
valueType("UTF8Text");
else
valueType("");
valueType(detail::MapTypeString<T>::value[0]);

// assign vector
if constexpr (runtime)
Expand Down
92 changes: 33 additions & 59 deletions src/GNDStk/BodyText/src/get.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -174,33 +174,13 @@ std::enable_if_t<
// length, start, and valueType.

// For this get(), the caller has stipulated a particular vector type.
// We'll print a warning if that type appears to conflict with valueType,
// or if valueType isn't something we know what to do with. In any event,
// we'll return what the caller requested. Note that valueType = "" (the
// empty string) is acceptable with any element type.

bool consistent = true;
if (valueType() == "Integer32") {
if (!std::is_same_v<T,Integer32>)
consistent = false;
} else if (valueType() == "Float64") {
if (!std::is_same_v<T,Float64>)
consistent = false;
} else if (valueType() == "UTF8Text") {
if (!std::is_same_v<T,UTF8Text>)
consistent = false;
} else if (valueType() != "") {
// We'll print a warning if that vector type appears to conflict with
// valueType. Regardless, we'll return what the caller requested. Note
// that valueType == "" is acceptable with any element type.
if (valueType() != "" && !detail::MapTypeString<T>::find(valueType())) {
log::warning(
"Unrecognized valueType == \"{}\"; ignoring",
valueType()
);
log::member(context_rebuilding);
}

if (!consistent) {
log::warning(
"Element type T may be inconsistent with valueType == \"{}\";\n",
"we'll create the requested std::vector<T> anyway",
"Vector element type may be inconsistent with valueType \"{}\";\n"
"we'll create the requested std::vector<> anyway",
valueType()
);
log::member(context_rebuilding);
Expand Down Expand Up @@ -401,16 +381,13 @@ std::conditional_t<
> get() const
{
if constexpr (runtime) {
if (valueType() == "Integer32")
get<std::vector<Integer32>>();
else if (valueType() == "Float64")
get<std::vector<Float64>>();
else
get<std::vector<std::string>>();

// We can't return the specific variant *alternative* that exists right
// now, because that depended on valueType (run-time). So, we'll return
// the whole variant, for whatever use that might have to a caller.
detail::MapStringType(
valueType(),
[this](auto &&t) { get<std::vector<std::decay_t<decltype(t)>>>(); }
);
// We can't return the specific variant alternative that was just put
// in place; it depended on a run-time check. So, we return the whole
// variant, for whatever use that might have to a caller.
return variant;
} else {
// Simpler, but we do still need a get (in case the *string* is active).
Expand Down Expand Up @@ -552,8 +529,8 @@ operator[](const std::size_t n)
template<class D = DATA> \
std::enable_if_t< \
detail::isVoid<D> || \
std::is_same_v<TYPE,D>, std::vector<TYPE> & \
> name() { return get<std::vector<TYPE>>(); } \
std::is_same_v<TYPE,D>, std::vector<TYPE> & \
> name() { return get<std::vector<TYPE>>(); } \
\
template<class D = DATA> \
std::enable_if_t< \
Expand All @@ -564,26 +541,23 @@ operator[](const std::size_t n)
template<class D = DATA> \
std::enable_if_t< \
detail::isVoid<D> || \
std::is_same_v<TYPE,D>, TYPE & \
> name(const std::size_t n) { return get<TYPE>(n); }

GNDSTK_MAKE_GETTER(strings, std::string);
GNDSTK_MAKE_GETTER(chars, char);

GNDSTK_MAKE_GETTER(schars, signed char);
GNDSTK_MAKE_GETTER(shorts, short);
GNDSTK_MAKE_GETTER(ints, int);
GNDSTK_MAKE_GETTER(longs, long);
GNDSTK_MAKE_GETTER(longlongs, long long);

GNDSTK_MAKE_GETTER(uchars, unsigned char);
GNDSTK_MAKE_GETTER(ushorts, unsigned short);
GNDSTK_MAKE_GETTER(uints, unsigned int);
GNDSTK_MAKE_GETTER(ulongs, unsigned long);
GNDSTK_MAKE_GETTER(ulonglongs, unsigned long long);

GNDSTK_MAKE_GETTER(floats, float);
GNDSTK_MAKE_GETTER(doubles, double);
GNDSTK_MAKE_GETTER(longdoubles, long double);
std::is_same_v<TYPE,D>, TYPE & \
> name(const std::size_t n) { return get<TYPE>(n); }

GNDSTK_MAKE_GETTER(strings, std::string)
GNDSTK_MAKE_GETTER(chars, char)
GNDSTK_MAKE_GETTER(schars, signed char)
GNDSTK_MAKE_GETTER(shorts, short)
GNDSTK_MAKE_GETTER(ints, int)
GNDSTK_MAKE_GETTER(longs, long)
GNDSTK_MAKE_GETTER(longlongs, long long)
GNDSTK_MAKE_GETTER(uchars, unsigned char)
GNDSTK_MAKE_GETTER(ushorts, unsigned short)
GNDSTK_MAKE_GETTER(uints, unsigned int)
GNDSTK_MAKE_GETTER(ulongs, unsigned long)
GNDSTK_MAKE_GETTER(ulonglongs, unsigned long long)
GNDSTK_MAKE_GETTER(floats, float)
GNDSTK_MAKE_GETTER(doubles, double)
GNDSTK_MAKE_GETTER(longdoubles, long double)

#undef GNDSTK_MAKE_GETTER
2 changes: 1 addition & 1 deletion src/GNDStk/BodyText/src/params.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Quoted [slightly edited] from the official JSON specification files for GNDS:
For start = N, the first N values are zero and are not stored.
valueType
Specifies the type of data in the body (e.g., Integer32, Float64).
Specifies the type of data in the body (e.g., "Integer32", "Float64").
Only one type of data can be stored in each instance of a values node.
In some places, e.g. the JSON-format GNDS spec files, these are listed in
Expand Down
17 changes: 4 additions & 13 deletions src/GNDStk/BodyText/src/toNode.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,19 +56,10 @@ void toNode(std::string &text, DERIVED &derived) const
// Compute length, start, and valueType
vars.length = size(); // independent of trim
vars.start = bounds.first; // dependent on trim, per the bounds computation
if constexpr (runtime) {
vars.valueType =
std::holds_alternative<std::vector<Integer32>>(variant) ? "Integer32"
: std::holds_alternative<std::vector<Float64 >>(variant) ? "Float64"
: std::holds_alternative<std::vector<UTF8Text >>(variant) ? "UTF8Text"
: ""; // fallback
} else {
vars.valueType =
std::is_same_v<Integer32,DATA> ? "Integer32"
: std::is_same_v<Float64, DATA> ? "Float64"
: std::is_same_v<UTF8Text, DATA> ? "UTF8Text"
: ""; // fallback
}
if constexpr (runtime)
vars.valueType = detail::visitMapTypeString(variant);
else
vars.valueType = detail::MapTypeString<DATA>::value[0];
pushToDerived(derived);

// Values
Expand Down
40 changes: 20 additions & 20 deletions src/GNDStk/BodyText/test/assign.test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,42 +67,42 @@ SCENARIO("BodyText<DATA == void> assignment operators") {
}
}

// Assign from vector<Integer32>; should set valueType
WHEN("We assign from a vector<Integer32>") {
// Assign from vector<int>; should set valueType
WHEN("We assign from a vector<int>") {
THEN("valueType is set correctly") {
BodyText<true,void> b;

b.string("foo").valueType("unknown");
CHECK(b.valueType() == "unknown");

b = std::vector<Integer32>{{10,20,30}};
b = std::vector<int>{{10,20,30}};
CHECK(b.valueType() == "Integer32");
}
}

// Assign from vector<Float64>; should set valueType
WHEN("We assign from a vector<Float64>") {
// Assign from vector<double>; should set valueType
WHEN("We assign from a vector<double>") {
THEN("valueType is set correctly") {
BodyText<true,void> b;

b.string("foo").valueType("unknown");
CHECK(b.valueType() == "unknown");

b = std::vector<Float64>{{1.23,4.56,7.89}};
b = std::vector<double>{{1.23,4.56,7.89}};
CHECK(b.valueType() == "Float64");
}
}

// For now, non-{Integer32,Float64} sets valueType == ""
WHEN("We assign from a vector<non-{Integer32,Float64}>") {
// For now, non-{int,double} sets valueType == ""
WHEN("We assign from a vector<non-{int,double}>") {
THEN("valueType is set correctly") {
BodyText<true,void> b;

b.string("foo").valueType("unknown");
CHECK(b.valueType() == "unknown");

b = std::vector<char>{'a','b','c'};
CHECK(b.valueType() == "");
CHECK(b.valueType() == "char");
}
}

Expand Down Expand Up @@ -172,42 +172,42 @@ SCENARIO("BodyText<DATA != void> assignment operators") {
}
}

// Assign from vector<Integer32>; should set valueType
WHEN("We assign from a vector<Integer32>") {
// Assign from vector<int>; should set valueType
WHEN("We assign from a vector<int>") {
THEN("valueType is set correctly") {
BodyText<true,Integer32> b;
BodyText<true,int> b;

b.string("foo").valueType("unknown");
CHECK(b.valueType() == "unknown");

b = std::vector<Integer32>{{10,20,30}};
b = std::vector<int>{{10,20,30}};
CHECK(b.valueType() == "Integer32");
}
}

// Assign from vector<Float64>; should set valueType
WHEN("We assign from a vector<Float64>") {
// Assign from vector<double>; should set valueType
WHEN("We assign from a vector<double>") {
THEN("valueType is set correctly") {
BodyText<true,Float64> b;
BodyText<true,double> b;

b.string("foo").valueType("unknown");
CHECK(b.valueType() == "unknown");

b = std::vector<Float64>{{1.23,4.56,7.89}};
b = std::vector<double>{{1.23,4.56,7.89}};
CHECK(b.valueType() == "Float64");
}
}

// For now, non-{Integer32,Float64} sets valueType == ""
WHEN("We assign from a vector<non-{Integer32,Float64}>") {
// For now, non-{int,double} sets valueType == ""
WHEN("We assign from a vector<non-{int,double}>") {
THEN("valueType is set correctly") {
BodyText<true,char> b;

b.string("foo").valueType("unknown");
CHECK(b.valueType() == "unknown");

b = std::vector<char>{'a','b','c'};
CHECK(b.valueType() == "");
CHECK(b.valueType() == "char");
}
}

Expand Down
Loading

0 comments on commit 208d078

Please sign in to comment.