1#ifndef OPENXLSX_XLCELLVALUE_HPP
2#define OPENXLSX_XLCELLVALUE_HPP
6# pragma warning(disable : 4251)
7# pragma warning(disable : 4275)
13#include <fast_float/fast_float.h>
15#include <fmt/format.h>
21#include "OpenXLSX-Exports.hpp"
27typedef std::variant<std::string, int64_t, double, bool, OpenXLSX::XLRichText>
XLCellValueType;
31 class XLCellValueProxy;
43 double operator()(int64_t v)
const {
return static_cast<double>(v); }
55 "string is not convertible to double.");
57 auto [ptr, ec] = fast_float::from_chars(v.data(), v.data() + v.size(), val);
58 if (ec != std::errc())
throw XLValueTypeError(
"string is not convertible to double.");
67 std::string
operator()(int64_t v)
const {
return fmt::format(
"{}", v); }
68 std::string
operator()(
double v)
const {
return fmt::format(
"{}", v); }
69 std::string
operator()(
bool v)
const {
return v ?
"true" :
"false"; }
72 std::string
operator()(std::string v)
const {
return v; }
90 friend std::hash<OpenXLSX::XLCellValue>;
92#define OPENXLSX_XLCELLVALUE_FRIEND_STRING_OP(OP, FUNCTOR) \
93 friend bool operator OP(const XLCellValue& lhs, std::string_view rhs) \
95 if (std::holds_alternative<std::string>(lhs.m_value)) \
96 return FUNCTOR<>{}(std::string_view(std::get<std::string>(lhs.m_value)), rhs); \
99 friend bool operator OP(std::string_view lhs, const XLCellValue& rhs) \
101 if (std::holds_alternative<std::string>(rhs.m_value)) \
102 return FUNCTOR<>{}(lhs, std::string_view(std::get<std::string>(rhs.m_value))); \
105 friend bool operator OP(const XLCellValue& lhs, const char* rhs) { return lhs OP std::string_view(rhs); } \
106 friend bool operator OP(const char* lhs, const XLCellValue& rhs) { return std::string_view(lhs) OP rhs; } \
107 friend bool operator OP(const XLCellValue& lhs, const std::string& rhs) { return lhs OP std::string_view(rhs); } \
108 friend bool operator OP(const std::string& lhs, const XLCellValue& rhs) { return std::string_view(lhs) OP rhs; }
117#undef OPENXLSX_XLCELLVALUE_FRIEND_STRING_OP
132 typename = std::enable_if_t<
133 std::is_integral_v<T> or std::is_floating_point_v<T> or std::is_same_v<std::decay_t<T>, std::string> ||
134 std::is_same_v<std::decay_t<T>, std::string_view> or std::is_same_v<std::decay_t<T>,
const char*> ||
135 std::is_same_v<std::decay_t<T>,
char*> or std::is_same_v<T, OpenXLSX::XLRichText> or std::is_same_v<T, XLDateTime>>>
139 if constexpr (std::is_integral_v<T> and std::is_same_v<T, bool>) {
140 m_type = XLValueType::Boolean;
145 else if constexpr (std::is_integral_v<T> and !std::is_same_v<T, bool>) {
146 m_type = XLValueType::Integer;
147 m_value =
static_cast<int64_t
>(value);
152 else if constexpr (std::is_same_v<std::decay_t<T>, std::string> or std::is_same_v<std::decay_t<T>, std::string_view> ||
153 std::is_same_v<std::decay_t<T>,
const char*> ||
154 (std::is_same_v<std::decay_t<T>,
char*> and !std::is_same_v<T, bool>))
156 m_type = XLValueType::String;
157 m_value = std::string(value);
161 else if constexpr (std::is_same_v<T, XLDateTime>) {
162 m_type = XLValueType::Float;
163 m_value = value.serial();
167 else if constexpr (std::is_same_v<T, XLRichText>) {
168 m_type = XLValueType::RichText;
175 static_assert(std::is_floating_point_v<T>,
"Invalid argument for constructing XLCellValue object");
176 if (std::isfinite(value)) {
177 m_type = XLValueType::Float;
178 m_value =
static_cast<double>(value);
181 m_type = XLValueType::Error;
182 m_value = std::string(
"#NUM!");
225 typename = std::enable_if_t<
226 std::is_integral_v<T> or std::is_floating_point_v<T> or std::is_same_v<std::decay_t<T>, std::string> ||
227 std::is_same_v<std::decay_t<T>, std::string_view> or std::is_same_v<std::decay_t<T>,
const char*> ||
228 std::is_same_v<std::decay_t<T>,
char*> or std::is_same_v<T, OpenXLSX::XLRichText> or std::is_same_v<T, XLDateTime>>>
233 std::swap(*
this, temp);
244 typename = std::enable_if_t<std::is_same_v<T, XLCellValue> or std::is_integral_v<T> or std::is_floating_point_v<T> ||
245 std::is_same_v<std::decay_t<T>, std::string> or std::is_same_v<std::decay_t<T>, std::string_view> ||
246 std::is_same_v<std::decay_t<T>,
const char*> or std::is_same_v<std::decay_t<T>,
char*> ||
247 std::is_same_v<T, OpenXLSX::XLRichText> or std::is_same_v<T, XLDateTime>>>
261 typename = std::enable_if_t<
262 std::is_integral_v<T> or std::is_floating_point_v<T> or std::is_same_v<std::decay_t<T>, std::string> ||
263 std::is_same_v<std::decay_t<T>, std::string_view> or std::is_same_v<std::decay_t<T>,
const char*> ||
264 std::is_same_v<std::decay_t<T>,
char*> or std::is_same_v<T, XLDateTime> or std::is_same_v<T, OpenXLSX::XLRichText>>>
268 return privateGet<T>();
271 catch (
const std::bad_variant_access&) {
272 throw XLValueTypeError(
"XLCellValue object does not contain the requested type.");
285 typename = std::enable_if_t<
286 std::is_integral_v<T> or std::is_floating_point_v<T> or std::is_same_v<std::decay_t<T>, std::string> ||
287 std::is_same_v<std::decay_t<T>, std::string_view> or std::is_same_v<std::decay_t<T>,
const char*> ||
288 std::is_same_v<std::decay_t<T>,
char*> or std::is_same_v<T, OpenXLSX::XLRichText> or std::is_same_v<T, XLDateTime>>>
292 if constexpr (std::is_integral_v<T> and std::is_same_v<T, bool>)
return std::get<bool>(m_value);
294 if constexpr (std::is_integral_v<T> and !std::is_same_v<T, bool>)
return static_cast<T
>(std::get<int64_t>(m_value));
296 if constexpr (std::is_floating_point_v<T>) {
297 return static_cast<T
>(getDouble());
303 if constexpr (std::is_same_v<std::decay_t<T>, std::string> or std::is_same_v<std::decay_t<T>, std::string_view> ||
304 std::is_same_v<std::decay_t<T>,
const char*> ||
305 (std::is_same_v<std::decay_t<T>,
char*> and !std::is_same_v<T, bool>))
306 return std::get<std::string>(m_value).c_str();
308 if constexpr (std::is_same_v<T, OpenXLSX::XLRichText>)
return std::get<OpenXLSX::XLRichText>(m_value);
310 if constexpr (std::is_same_v<T, XLDateTime>)
311 return XLDateTime(getDouble());
315 catch (
const std::bad_variant_access&) {
316 throw XLValueTypeError(
"XLCellValue object does not contain the requested type.");
328 if (m_type == XLValueType::Error)
return static_cast<double>(std::nan(
"1"));
366 typename = std::enable_if_t<
367 std::is_integral_v<T> or std::is_floating_point_v<T> or std::is_same_v<std::decay_t<T>, std::string> ||
368 std::is_same_v<std::decay_t<T>, std::string_view> or std::is_same_v<std::decay_t<T>,
const char*> ||
369 std::is_same_v<std::decay_t<T>,
char*> or std::is_same_v<T, OpenXLSX::XLRichText> or std::is_same_v<T, XLDateTime>>>
371 {
return this->get<T>(); }
395 const char* typeAsString()
const;
399 XLValueType m_type{XLValueType::Empty};
433 typename = std::enable_if_t<
434 std::is_integral_v<T> or std::is_floating_point_v<T> or std::is_same_v<std::decay_t<T>, std::string> ||
435 std::is_same_v<std::decay_t<T>, std::string_view> or std::is_same_v<std::decay_t<T>,
const char*> ||
436 std::is_same_v<std::decay_t<T>,
char*> or std::is_same_v<T, XLCellValue> or std::is_same_v<T, XLDateTime> or
437 std::is_same_v<T, OpenXLSX::XLRichText>>>
441 if constexpr (std::is_integral_v<T> and std::is_same_v<T, bool>)
444 else if constexpr (std::is_integral_v<T> and !std::is_same_v<T, bool>)
447 else if constexpr (std::is_floating_point_v<T>)
450 else if constexpr (std::is_same_v<T, XLDateTime>)
451 setFloat(value.serial());
453 else if constexpr (std::is_same_v<T, OpenXLSX::XLRichText>)
456 else if constexpr (std::is_same_v<std::decay_t<T>, std::string> or std::is_same_v<std::decay_t<T>, std::string_view> ||
457 std::is_same_v<std::decay_t<T>,
const char*> ||
458 (std::is_same_v<std::decay_t<T>,
char*> and !std::is_same_v<T, bool> and !std::is_same_v<T, XLCellValue>))
463 if constexpr (std::is_same_v<T, XLCellValue>) {
464 switch (value.type()) {
465 case XLValueType::Boolean:
466 setBoolean(value.template get<bool>());
468 case XLValueType::Integer:
469 setInteger(value.template get<int64_t>());
471 case XLValueType::Float:
472 setFloat(value.template get<double>());
474 case XLValueType::String:
475 setString(value.template privateGet<const char*>());
477 case XLValueType::RichText:
478 setRichText(value.template get<OpenXLSX::XLRichText>());
480 case XLValueType::Empty:
498 typename = std::enable_if_t<
499 std::is_integral_v<T> or std::is_floating_point_v<T> or std::is_same_v<std::decay_t<T>, std::string> ||
500 std::is_same_v<std::decay_t<T>, std::string_view> or std::is_same_v<std::decay_t<T>,
const char*> ||
501 std::is_same_v<std::decay_t<T>,
char*> or std::is_same_v<T, XLCellValue> or std::is_same_v<T, XLDateTime> or
502 std::is_same_v<T, OpenXLSX::XLRichText>>>
511 typename = std::enable_if_t<
512 std::is_integral_v<T> or std::is_floating_point_v<T> or std::is_same_v<std::decay_t<T>, std::string> ||
513 std::is_same_v<std::decay_t<T>, std::string_view> or std::is_same_v<std::decay_t<T>,
const char*> ||
514 std::is_same_v<std::decay_t<T>,
char*> or std::is_same_v<T, OpenXLSX::XLRichText> or std::is_same_v<T, XLDateTime>>>
517 if constexpr (std::is_same_v<std::decay_t<T>, std::string_view> || std::is_same_v<std::decay_t<T>,
const char*>) {
518 auto view = getStringView();
519 if constexpr (std::is_same_v<std::decay_t<T>,
const char*>)
return view.data();
522 else if constexpr (std::is_same_v<std::decay_t<T>, std::string>) {
523 return std::string(getStringView());
526 return getValue().get<T>();
552 const char* typeAsString()
const;
566 typename = std::enable_if_t<
567 std::is_integral_v<T> or std::is_floating_point_v<T> or std::is_same_v<std::decay_t<T>, std::string> ||
568 std::is_same_v<std::decay_t<T>, std::string_view> or std::is_same_v<std::decay_t<T>,
const char*> ||
569 std::is_same_v<std::decay_t<T>,
char*> or std::is_same_v<T, OpenXLSX::XLRichText> or std::is_same_v<T, XLDateTime>>>
571 {
return getValue().get<T>(); }
583 std::string_view getStringView()
const;
589 catch (std::string s) {
625 void setInteger(int64_t numberValue);
631 void setBoolean(
bool numberValue);
637 void setFloat(
double numberValue);
643 void setString(std::string_view stringValue);
649 void setRichText(
const XLRichText& richTextValue);
662 int32_t stringIndex()
const;
669 bool setStringIndex(int32_t newIndex);
681 template<
typename Op>
682 struct XLCompareVisitor
684 template<
typename T,
typename U>
685 bool operator()(
const T& lhs,
const U& rhs)
const
687 if constexpr (std::is_arithmetic_v<T> && std::is_arithmetic_v<U> && !std::is_same_v<T, bool> && !std::is_same_v<U, bool>) {
688 return Op{}(lhs, rhs);
690 else if constexpr (std::is_same_v<T, bool> && std::is_same_v<U, bool>) {
691 return Op{}(lhs, rhs);
693 else if constexpr (std::is_same_v<T, std::string> && std::is_same_v<U, std::string>) {
694 return Op{}(lhs, rhs);
707 {
return std::visit(XLCompareVisitor<std::equal_to<>>{}, lhs.m_value, rhs.m_value); }
714 {
return std::visit(XLCompareVisitor<std::not_equal_to<>>{}, lhs.m_value, rhs.m_value); }
721 {
return std::visit(XLCompareVisitor<std::less<>>{}, lhs.m_value, rhs.m_value); }
728 {
return std::visit(XLCompareVisitor<std::greater<>>{}, lhs.m_value, rhs.m_value); }
735 {
return std::visit(XLCompareVisitor<std::less_equal<>>{}, lhs.m_value, rhs.m_value); }
742 {
return std::visit(XLCompareVisitor<std::greater_equal<>>{}, lhs.m_value, rhs.m_value); }
750 switch (value.
type()) {
754 return os << value.
get<
bool>();
756 return os << value.
get<int64_t>();
758 return os << value.
get<
double>();
760 return os << value.
get<std::string>();
771 switch (value.
type()) {
775 return os << value.
get<
bool>();
777 return os << value.
get<int64_t>();
779 return os << value.
get<
double>();
781 return os << value.
get<std::string>();
799 std::size_t h = std::hash<std::string>{}(run.text());
800 if (run.bold()) h ^= std::hash<bool>{}(*run.bold()) + 0x9e3779b9 + (h << 6) + (h >> 2);
801 if (run.italic()) h ^= std::hash<bool>{}(*run.italic()) + 0x9e3779b9 + (h << 6) + (h >> 2);
812 for (
const auto& run : rt.runs()) { h ^= std::hash<OpenXLSX::XLRichTextRun>{}(run) + 0x9e3779b9 + (h << 6) + (h >> 2); }
822 return std::visit([](
const auto& v) {
return std::hash<std::decay_t<
decltype(v)>>{}(v); }, value.getVariant());
#define OPENXLSX_XLCELLVALUE_FRIEND_STRING_OP(OP, FUNCTOR)
Definition XLCellValue.hpp:92
std::variant< std::string, int64_t, double, bool, OpenXLSX::XLRichText > XLCellValueType
Definition XLCellValue.hpp:27
Definition XLXmlParser.hpp:84
The XLCellValueProxy class is used for proxy (or placeholder) objects for XLCellValue objects.
Definition XLCellValue.hpp:408
XLCellValueProxy & operator=(const T &value)
Templated assignment operator.
Definition XLCellValue.hpp:438
std::string getString() const
Definition XLCellValue.hpp:584
T get() const
Definition XLCellValue.hpp:515
~XLCellValueProxy()
Destructor.
void set(const T &value)
Sets the cell value using an automatically deduced type proxy.
Definition XLCellValue.hpp:503
XLValueType type() const
Get the value type for the cell.
Definition XLCellValue.cpp:245
Class encapsulating a cell value.
Definition XLCellValue.hpp:79
void set(T numberValue)
Templated setter for integral and bool types.
Definition XLCellValue.hpp:248
XLCellValue(XLCellValue &&other) noexcept
Move constructor.
double getDouble() const
get the cell value as a double, regardless of value type
Definition XLCellValue.hpp:326
XLCellValue & operator=(T value)
Templated assignment operator.
Definition XLCellValue.hpp:229
const XLCellValueType & getVariant() const
get the cell value as a std::variant of XLCellValueType
Definition XLCellValue.hpp:356
std::string getString()
get the cell value as a std::string, regardless of value type
Definition XLCellValue.hpp:342
~XLCellValue()
Destructor.
XLCellValue(const XLCellValue &other)
Copy constructor.
XLCellValue & operator=(const XLCellValue &other)
Copy assignment operator.
XLValueType type() const
Get the value type of the current object.
Definition XLCellValue.cpp:94
T get() const
Templated getter.
Definition XLCellValue.hpp:265
XLCellValue(const T &value)
A templated constructor. Any value convertible to a valid cell value can be used as argument.
Definition XLCellValue.hpp:136
XLCellValue & operator=(XLCellValue &&other) noexcept
Move assignment operator.
XLCellValue()
Default constructor.
An implementation class encapsulating the properties and behaviours of a spreadsheet cell.
Definition XLCell.hpp:41
This class encapsulates the concept of an excel file. It is different from the XLWorkbook,...
Definition XLDocument.hpp:82
A class representing a single run of rich text.
Definition XLRichText.hpp:20
A class representing rich text in a cell.
Definition XLRichText.hpp:129
std::string plainText() const
Get the plain text representation of the rich text.
Definition XLRichText.hpp:150
Definition XLException.hpp:41
Definition IZipArchive.hpp:18
bool operator==(const XLCell &lhs, const XLCell &rhs)
Definition XLCell.hpp:304
bool operator!=(const XLCell &lhs, const XLCell &rhs)
Definition XLCell.hpp:311
bool operator<=(const XLCellReference &lhs, const XLCellReference &rhs) noexcept
Asserts whether a cell sequentially precedes or occupies the exact same coordinate as another.
Definition XLCellReference.hpp:244
bool operator<(const XLCellReference &lhs, const XLCellReference &rhs) noexcept
Evaluates precedence primarily by row, then by column, allowing cell ranges to be sorted efficiently ...
Definition XLCellReference.hpp:233
bool operator>=(const XLCellReference &lhs, const XLCellReference &rhs) noexcept
Asserts whether a cell sequentially follows or occupies the exact same coordinate as another.
Definition XLCellReference.hpp:249
XLValueType
Enum defining the valid value types for a an Excel spreadsheet cell.
Definition XLCellValue.hpp:37
bool operator>(const XLCellReference &lhs, const XLCellReference &rhs) noexcept
Inverts the less-than operator logic to verify strict left-to-right, top-to-bottom traversal dominanc...
Definition XLCellReference.hpp:239
std::ostream & operator<<(std::ostream &os, const XLCell &c)
ostream output of XLCell content
Definition XLCell.hpp:319
Definition XLCellIterator.hpp:121
Definition XLCellValue.hpp:41
std::string packageName
Definition XLCellValue.hpp:42
double operator()(std::string v) const
Definition XLCellValue.hpp:52
double operator()(int64_t v) const
Definition XLCellValue.hpp:43
double operator()(double v) const
Definition XLCellValue.hpp:44
double operator()(bool v) const
Definition XLCellValue.hpp:45
double operator()(const OpenXLSX::XLRichText &v) const
Definition XLCellValue.hpp:47
Definition XLCellValue.hpp:65
std::string operator()(bool v) const
Definition XLCellValue.hpp:69
std::string operator()(int64_t v) const
Definition XLCellValue.hpp:67
std::string operator()(double v) const
Definition XLCellValue.hpp:68
std::string operator()(std::string v) const
Definition XLCellValue.hpp:72
std::string packageName
Definition XLCellValue.hpp:66
std::string operator()(const XLRichText &v) const
Definition XLCellValue.hpp:71
std::size_t operator()(const OpenXLSX::XLCellValue &value) const noexcept
Definition XLCellValue.hpp:820
std::size_t operator()(const OpenXLSX::XLRichTextRun &run) const noexcept
Definition XLCellValue.hpp:797
std::size_t operator()(const OpenXLSX::XLRichText &rt) const noexcept
Definition XLCellValue.hpp:809