Skip to content

Commit

Permalink
Updating ...
Browse files Browse the repository at this point in the history
  • Loading branch information
whaeck committed Oct 21, 2021
2 parents b8cc2c8 + 542025b commit a294af1
Show file tree
Hide file tree
Showing 40 changed files with 2,988 additions and 346 deletions.
28 changes: 26 additions & 2 deletions autogen/json2class.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1163,7 +1163,8 @@ void write_class_ctor(
std::ostream &os,
const std::string &clname,
const std::vector<infoMetadata> &vecInfoMetadata,
const std::vector<infoChildren> &vecInfoChildren
const std::vector<infoChildren> &vecInfoChildren,
const bool hasBodyText, const bool hasData
) {
std::size_t count;
os << "\n";
Expand Down Expand Up @@ -1287,6 +1288,24 @@ void write_class_ctor(

// body
write_ctor_body(os,"");

// ------------------------
// ctor: vector
// ------------------------

if (hasBodyText || hasData) {
// signature, and base constructor call
os << "\n";
os << " // from vector\n";
os << " template<class T, class = "
<< "std::enable_if_t<body::template supported<T>>>\n";
os << " " << clname << "(const std::vector<T> &vector) :\n";
write_component_base(os, vecInfoMetadata, vecInfoChildren, false);

// body
os << "\n";
write_ctor_body(os,"vector");
}
}


Expand Down Expand Up @@ -1515,6 +1534,8 @@ void make_class(

// output: base
oss << "\n using Component::construct;\n";
if (hasBodyText || hasData)
oss << " using BodyText::operator=;\n";

// output: defaults (applicable only to metadata)
oss << "\n " << small;
Expand Down Expand Up @@ -1554,7 +1575,10 @@ void make_class(
<< "\n // Construction"
<< "\n " << small
<< "\n";
write_class_ctor(oss, clname, vecInfoMetadata, vecInfoChildren);
write_class_ctor(
oss, clname, vecInfoMetadata, vecInfoChildren,
hasBodyText, hasData
);

// output: class end
write_class_suffix(oss, file_namespace, clname);
Expand Down
1 change: 1 addition & 0 deletions cmake/unit_testing.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ add_subdirectory( src/GNDStk/convert/test )
add_subdirectory( src/GNDStk/utility/test )
add_subdirectory( src/GNDStk/Component/test )
add_subdirectory( src/GNDStk/BodyText/test )
add_subdirectory( src/GNDStk/precision/test )

add_subdirectory( src/GNDStk/enums/Encoding/test )
add_subdirectory( src/GNDStk/enums/Frame/test )
Expand Down
2 changes: 2 additions & 0 deletions src/GNDStk.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@
#include <algorithm>
#include <cassert>
#include <cctype>
#ifdef GNDSTK_PRECISION
#include <charconv>
#endif
#include <chrono>
#include <cmath>
#include <cstdint>
Expand Down
26 changes: 18 additions & 8 deletions src/GNDStk/BodyText.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ class BodyText {
public:
using VariantOfVectors = std::variant<std::monostate>;
using VariantOfScalars = std::variant<std::monostate>;
static inline constexpr bool runtime = false;
template<class T>
static inline constexpr bool supported = false;
};


Expand All @@ -40,23 +43,27 @@ class BodyText<true,DATA> {

#include "GNDStk/BodyText/src/types.hpp"

private:

// For internal use
enum class Active { string, vector };
mutable Active active = Active::string;

// For convenience in various SFINAE and if-constexpr constructs
static inline constexpr bool runtime = detail::isVoid<DATA>;
template<class T>
struct is_supported {
static inline constexpr bool value =
( runtime && detail::isAlternative<T,VariantOfScalars>) ||
(!runtime && std::is_same_v<T,DATA>);
(!runtime && (
std::is_constructible_v<DATA,T> ||
std::is_convertible_v<T,DATA>
));
};
template<class T>
static inline constexpr bool supported = is_supported<T>::value;

enum class Active { string, vector };

private:

// For internal use
mutable Active act = Active::string;

// Raw string, directly from "plain character data" in a GNDS file.
// We'll allow callers to set this by using a setter.
std::string rawstring;
Expand Down Expand Up @@ -91,6 +98,9 @@ class BodyText<true,DATA> {
// Getters and setters for the raw string:
#include "GNDStk/BodyText/src/string.hpp"

// active()
Active active() const { return act; }

// clear()
// Clears the vector, or the active vector alternative in the variant.
BodyText &clear()
Expand All @@ -100,7 +110,7 @@ class BodyText<true,DATA> {
else
vector.clear();

active = Active::vector;
act = Active::vector;
return *this;
}

Expand Down
10 changes: 8 additions & 2 deletions src/GNDStk/BodyText/src/assign.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,15 @@ operator=(const std::vector<T> &vec)
// assign vector
if constexpr (runtime)
variant = vec;
else
else if constexpr (std::is_same_v<T,DATA>)
vector = vec;
else {
vector.clear();
vector.reserve(vec.size());
for (const T &element : vec)
vector.push_back(DATA(element));
}

active = Active::vector;
act = Active::vector;
return *this;
}
41 changes: 20 additions & 21 deletions src/GNDStk/BodyText/src/detail.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,39 +116,38 @@ inline constexpr bool hasLabel = has_label <std::decay_t<T>>::value;
// element2element
// -----------------------------------------------------------------------------

// todo: Determine if GNDStk's convert() functions can handle all possible
// cases here, or could be extended to do so.

// arithmetic ==> string
template<class T, class = std::enable_if_t<!std::is_same_v<T,std::string>>>
void element2element(const T &value, std::string &str)
{
if constexpr (std::is_floating_point_v<T>) {
str = Precision<PrecisionContext::data,T>{}.write(value);
} else {
std::ostringstream oss;
oss << value;
str = oss.str();
}
}
// Remark: PrecisionContext::data, not PrecisionContext::metadata, is the right
// precision context (in terms of our functionality for handling floating-point
// precision) in the code for which element2element() is called. We could bypass
// element2element() entirely, using convert_t{}(...) instead, except that then
// PrecisionContext::metadata would ultimately get used for floating-point T.
// So, below, we recognize floating-point T directly, and handle it correctly.

// string ==> arithmetic
template<class T, class = std::enable_if_t<!std::is_same_v<T,std::string>>>
void element2element(const std::string &str, T &value)
{
if constexpr (std::is_floating_point_v<T>) {
if constexpr (std::is_floating_point_v<T>)
value = Precision<PrecisionContext::data,T>{}.read(str);
} else {
std::istringstream iss(str);
iss >> value;
}
else
convert_t{}(str,value);
}

// arithmetic ==> arithmetic
template<class FROM, class TO>
void element2element(const FROM &from, TO &to)
{
to = TO(from);
convert_t{}(from,to);
}

// arithmetic ==> string
template<class T, class = std::enable_if_t<!std::is_same_v<T,std::string>>>
void element2element(const T &value, std::string &str)
{
if constexpr (std::is_floating_point_v<T>)
str = Precision<PrecisionContext::data,T>{}.write(value);
else
convert_t{}(value,str);
}


Expand Down
2 changes: 1 addition & 1 deletion src/GNDStk/BodyText/src/fromNode.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,5 @@ void fromNode(const Node &node)
// Above, we set the raw string. The following reflects this, so that the
// vector, or a vector in the variant, will be rebuilt from the raw string
// if and when a caller asks for it.
active = Active::string;
act = Active::string;
}
21 changes: 15 additions & 6 deletions src/GNDStk/BodyText/src/get.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ std::enable_if_t<
// if active == string
// ------------------------

if (active == Active::string) {
if (active() == Active::string) {
static const std::string context_rebuilding =
"BodyText::get<std::vector<T>>(), remade from raw string";

Expand Down Expand Up @@ -257,7 +257,7 @@ std::enable_if_t<
for (std::size_t i = to->size(); i < length(); ++i)
to->push_back(zero);

active = Active::vector; // was string; now is vector
act = Active::vector; // was string; now is vector
return *to;
} // if (active == Active::string)

Expand Down Expand Up @@ -348,16 +348,22 @@ std::enable_if_t<
// when using a BodyText object, we recommend sticking with one underlying type.

// For DATA != void (so that we have a vector):
// T == DATA is required. (So that returning an element of the vector<DATA> will
// return a reference to T.)
// T == DATA is required, so that returning an element of the vector<DATA> will
// return a reference to T. (A constructibility/convertibility requirement that
// we have in other BodyText-related code thus needs to be more stringent here.
// We can't just be able to make a T from a DATA. Those must in fact be the same
// type, because we return a reference.)

// For both of the above cases:
// If the string (not the variant or the vector) is active, then a rebuild from
// the string is necessary, and will happen in the get<std::vector<T>>() call.

// const
template<class T>
std::enable_if_t<supported<T>, const T &>
std::enable_if_t<
supported<T> && (runtime || std::is_same_v<T,DATA>),
const T &
>
get(const std::size_t n) const
{
try {
Expand All @@ -370,7 +376,10 @@ get(const std::size_t n) const

// non-const
template<class T>
std::enable_if_t<supported<T>, T &>
std::enable_if_t<
supported<T> && (runtime || std::is_same_v<T,DATA>),
T &
>
get(const std::size_t n)
{
return const_cast<T &>(std::as_const(*this).template get<T>(n));
Expand Down
2 changes: 1 addition & 1 deletion src/GNDStk/BodyText/src/string.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,6 @@ BodyText &string(const std::string &str)
{
clear(); // <== the vector, because it's no longer considered meaningful
rawstring = str;
active = Active::string;
act = Active::string;
return *this;
}
9 changes: 5 additions & 4 deletions src/GNDStk/BodyText/src/toNode.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ template<class DERIVED>
void toNode(std::string &text, DERIVED &derived) const
{
// Use the raw string?
if (active == Active::string) {
if (active() == Active::string) {
text = rawstring;
return;
}
Expand Down Expand Up @@ -83,9 +83,10 @@ void toNode(std::string &text, DERIVED &derived) const
for (auto i = bounds.first; i < bounds.second; ++i) {
oss << (count++ ? " " : "");
if constexpr (std::is_floating_point_v<T>) {
using detail::Precision;
using detail::PrecisionContext;
oss << Precision<PrecisionContext::data,T>{}.write(vec[i]);
oss << detail::Precision<
detail::PrecisionContext::data,
T
>{}.write(vec[i]);
} else {
oss << vec[i];
}
Expand Down
12 changes: 7 additions & 5 deletions src/GNDStk/BodyText/src/write.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@
std::ostream &write(std::ostream &os, const int level) const
{
// If empty, don't even write a newline
if ((active == Active::string && rawstring == "") ||
(active == Active::vector && size() == 0))
if ((active() == Active::string && rawstring == "") ||
(active() == Active::vector && size() == 0))
return os;

// ------------------------
// If string is active
// ------------------------

if (active == Active::string) {
if (active() == Active::string) {
// write the string exactly as-is, without our column formatting
// or any indentation; then also write a newline
GNDStk::color && GNDStk::colors::value != ""
Expand Down Expand Up @@ -49,8 +49,10 @@ std::ostream &write(std::ostream &os, const int level) const
os << colors::value;

if constexpr (std::is_floating_point_v<T>)
os << detail::Precision<detail::PrecisionContext::data,T>{}.
write(element);
os << detail::Precision<
detail::PrecisionContext::data,
T
>{}.write(element);
else
os << element;

Expand Down
Loading

0 comments on commit a294af1

Please sign in to comment.