From 7ec6e2d4dfa885a1c9e555c0903afbf8cc11fa64 Mon Sep 17 00:00:00 2001 From: Thomas Fussell Date: Tue, 3 Nov 2015 14:53:48 -0500 Subject: [PATCH] finish documenting all classes in cell module and clean up their APIs --- include/xlnt/cell/cell.hpp | 5 +- include/xlnt/cell/cell_reference.hpp | 26 +- include/xlnt/cell/comment.hpp | 38 ++- include/xlnt/cell/types.hpp | 309 +++++++++++++++++- include/xlnt/config.hpp | 1 + include/xlnt/utils/exceptions.hpp | 2 +- include/xlnt/worksheet/range_reference.hpp | 7 +- source/cell/cell.cpp | 6 +- source/cell/cell_reference.cpp | 72 +--- source/cell/types.cpp | 77 +++++ source/detail/cell_impl.cpp | 2 +- source/detail/constants.cpp | 39 ++- source/detail/constants.hpp | 8 +- source/serialization/worksheet_serializer.cpp | 12 +- source/utils/exceptions.cpp | 6 +- source/worksheet/range.cpp | 12 +- source/worksheet/range_reference.cpp | 6 +- source/worksheet/tests/test_worksheet.hpp | 4 +- source/worksheet/worksheet.cpp | 21 +- 19 files changed, 504 insertions(+), 149 deletions(-) create mode 100644 source/cell/types.cpp diff --git a/include/xlnt/cell/cell.hpp b/include/xlnt/cell/cell.hpp index b4933248..9944bac9 100644 --- a/include/xlnt/cell/cell.hpp +++ b/include/xlnt/cell/cell.hpp @@ -140,8 +140,7 @@ class cell // position cell_reference get_reference() const; - std::string get_column() const; - column_t get_column_index() const; + column_t get_column() const; row_t get_row() const; std::pair get_anchor() const; @@ -203,7 +202,7 @@ class cell std::string get_error() const; void set_error(const std::string &error); - cell offset(row_t row, column_t column); + cell offset(int column, int row); worksheet get_parent(); const worksheet get_parent() const; diff --git a/include/xlnt/cell/cell_reference.hpp b/include/xlnt/cell/cell_reference.hpp index a94c01e6..e052ceb7 100644 --- a/include/xlnt/cell/cell_reference.hpp +++ b/include/xlnt/cell/cell_reference.hpp @@ -52,26 +52,6 @@ struct cell_reference_hash class cell_reference { public: - /// - /// Convert a column letter into a column number (e.g. B -> 2) - /// - /// - /// Excel only supports 1 - 3 letter column names from A->ZZZ, so we - /// restrict our column names to 1 - 3 characters, each in the range A - Z. - /// Strings outside this range and malformed strings will throw xlnt::column_string_index_exception. - /// - static column_t column_index_from_string(const std::string &column_string); - - /// - /// Convert a column number into a column letter (3 -> 'C') - /// - /// - /// Right shift the column, column_index, by 26 to find column letters in reverse - /// order. These indices are 1-based, and can be converted to ASCII - /// ordinals by adding 64. - /// - static std::string column_string_from_index(column_t column_index); - /// /// Split a coordinate string like "A1" into an equivalent pair like {"A", 1}. /// @@ -173,9 +153,9 @@ class cell_reference /// Return a string that identifies the column of this reference /// (e.g. second column from left is "B") /// - std::string get_column() const + column_t get_column() const { - return column_string_from_index(column_); + return column_; } /// @@ -183,7 +163,7 @@ class cell_reference /// void set_column(const std::string &column_string) { - column_ = column_index_from_string(column_string); + column_ = column_t(column_string); } /// diff --git a/include/xlnt/cell/comment.hpp b/include/xlnt/cell/comment.hpp index e25f00a4..24808d6a 100644 --- a/include/xlnt/cell/comment.hpp +++ b/include/xlnt/cell/comment.hpp @@ -5,12 +5,7 @@ namespace xlnt { class cell; - -namespace detail { - -struct comment_impl; - -} // namespace detail +namespace detail { struct comment_impl; } /// /// A comment can be applied to a cell to provide extra information. @@ -22,22 +17,45 @@ class comment /// The default constructor makes an invalid comment without a parent cell. /// comment(); + + /// + /// Constructs a comment applied to the given cell, parent, and with the comment + /// text and author set to the provided respective values. comment(cell parent, const std::string &text, const std::string &auth); + ~comment(); - + + /// + /// Return the text that will be displayed for this comment. + /// std::string get_text() const; + + /// + /// Return the author of this comment. + /// std::string get_author() const; /// - /// True if the comments point to the same sell. - /// Note that a cell can only have one comment and a comment + /// True if the comments point to the same sell (false if + /// they are different cells but identical comments). Note + /// that a cell can only have one comment and a comment /// can only be applied to one cell. /// bool operator==(const comment &other) const; private: - friend class cell; + friend class cell; // cell needs access to private constructor + + /// + /// Construct a comment from an implementation of a comment. + /// comment(detail::comment_impl *d); + + /// + /// Pointer to the implementation of this comment. + /// This allows comments to be passed by value while + /// retaining the ability to modify the parent cell. + /// detail::comment_impl *d_; }; diff --git a/include/xlnt/cell/types.hpp b/include/xlnt/cell/types.hpp index e82d506e..d81fe775 100644 --- a/include/xlnt/cell/types.hpp +++ b/include/xlnt/cell/types.hpp @@ -22,10 +22,317 @@ // @author: see AUTHORS file #pragma once +#include #include +#include // We might want to change these types for various optimizations in the future // so use typedefs. +namespace xlnt { + +/// +/// All rows should be referred to by an instance of this type. +/// using row_t = std::uint32_t; -using column_t = std::uint32_t; + +/// +/// Columns can be referred to as a string A,B,...Z,AA,AB,..,ZZ,AAA,...,ZZZ +/// or as a 1-indexed index. This class encapsulates both of these forms of +/// column referencing and allows for convertions between them. +/// +class column_t +{ +public: + using index_t = std::uint32_t; + + /// + /// Convert a column letter into a column number (e.g. B -> 2) + /// + /// + /// Excel only supports 1 - 3 letter column names from A->ZZZ, so we + /// restrict our column names to 1 - 3 characters, each in the range A - Z. + /// Strings outside this range and malformed strings will throw xlnt::column_string_index_exception. + /// + static index_t column_index_from_string(const std::string &column_string); + + /// + /// Convert a column number into a column letter (3 -> 'C') + /// + /// + /// Right shift the column, column_index, by 26 to find column letters in reverse + /// order. These indices are 1-based, and can be converted to ASCII + /// ordinals by adding 64. + /// + static std::string column_string_from_index(index_t column_index); + + /// + /// Default column_t is the first (left-most) column. + /// + column_t() : index(1) {} + + /// + /// Construct a column from a number. + /// + column_t(index_t column_index) : index(column_index) {} + + /// + /// Construct a column from a string. + /// + explicit column_t(const std::string &column_string) : index(column_index_from_string(column_string)) {} + + /// + /// Construct a column from a string. + /// + explicit column_t(const char *column_string) : column_t(std::string(column_string)) {} + + /// + /// Copy constructor + /// + column_t(const column_t &other) : column_t(other.index) {} + + /// + /// Move constructor + /// + column_t(column_t &&other) { swap(*this, other); } + + /// + /// Return a string representation of this column index. + /// + std::string column_string() const { return column_string_from_index(index); } + + /// + /// Set this column to be the same as rhs's and return reference to self. + /// + column_t &operator=(column_t rhs) { swap(*this, rhs); return *this; } + + /// + /// Set this column to be equal to rhs and return reference to self. + /// + column_t &operator=(const std::string &rhs) { return *this = column_t(rhs); } + + /// + /// Set this column to be equal to rhs and return reference to self. + /// + column_t &operator=(const char *rhs) { return *this = column_t(rhs); } + + /// + /// Return true if this column refers to the same column as other. + /// + bool operator==(const column_t &other) const { return index == other.index; } + + /// + /// Return true if this column doesn't refer to the same column as other. + /// + bool operator!=(const column_t &other) const { return !(*this == other); } + + /// + /// Return true if this column refers to the same column as other. + /// + bool operator==(int other) const { return *this == column_t(other); } + + /// + /// Return true if this column refers to the same column as other. + /// + bool operator==(index_t other) const { return *this == column_t(other); } + + /// + /// Return true if this column refers to the same column as other. + /// + bool operator==(const std::string &other) const { return *this == column_t(other); } + + /// + /// Return true if this column refers to the same column as other. + /// + bool operator==(const char *other) const { return *this == column_t(other); } + + /// + /// Return true if this column doesn't refer to the same column as other. + /// + bool operator!=(int other) const { return !(*this == other); } + + /// + /// Return true if this column doesn't refer to the same column as other. + /// + bool operator!=(index_t other) const { return !(*this == other); } + + /// + /// Return true if this column doesn't refer to the same column as other. + /// + bool operator!=(const std::string &other) const { return !(*this == other); } + + /// + /// Return true if this column doesn't refer to the same column as other. + /// + bool operator!=(const char *other) const { return !(*this == other); } + + /// + /// Return true if other is to the right of this column. + /// + bool operator>(const column_t &other) const { return index > other.index; } + + /// + /// Return true if other is to the right of or equal to this column. + /// + bool operator>=(const column_t &other) const { return index >= other.index; } + + /// + /// Return true if other is to the left of this column. + /// + bool operator<(const column_t &other) const { return index < other.index; } + + /// + /// Return true if other is to the left of or equal to this column. + /// + bool operator<=(const column_t &other) const { return index <= other.index; } + + /// + /// Return true if other is to the right of this column. + /// + bool operator>(const column_t::index_t &other) const { return index > other; } + + /// + /// Return true if other is to the right of or equal to this column. + /// + bool operator>=(const column_t::index_t &other) const { return index >= other; } + + /// + /// Return true if other is to the left of this column. + /// + bool operator<(const column_t::index_t &other) const { return index < other; } + + /// + /// Return true if other is to the left of or equal to this column. + /// + bool operator<=(const column_t::index_t &other) const { return index <= other; } + + /// + /// Pre-increment this column, making it point to the column one to the right. + /// + column_t &operator++() { index++; return *this; } + + /// + /// Pre-deccrement this column, making it point to the column one to the left. + /// + column_t &operator--() { index--; return *this; } + + /// + /// Post-increment this column, making it point to the column one to the right and returning the old column. + /// + column_t operator++(int) { column_t copy(index); ++(*this); return copy; } + + /// + /// Post-decrement this column, making it point to the column one to the left and returning the old column. + /// + column_t operator--(int) { column_t copy(index); --(*this); return copy; } + + /// + /// Return the result of adding rhs to this column. + /// + column_t operator+(const column_t &rhs) { column_t copy(*this); copy.index += rhs.index; return copy; } + + /// + /// Return the result of adding rhs to this column. + /// + column_t operator-(const column_t &rhs) { column_t copy(*this); copy.index -= rhs.index; return copy; } + + /// + /// Return the result of adding rhs to this column. + /// + column_t operator*(const column_t &rhs) { column_t copy(*this); copy.index *= rhs.index; return copy; } + + /// + /// Return the result of adding rhs to this column. + /// + column_t operator/(const column_t &rhs) { column_t copy(*this); copy.index /= rhs.index; return copy; } + + /// + /// Return the result of adding rhs to this column. + /// + column_t operator%(const column_t &rhs) { column_t copy(*this); copy.index %= rhs.index; return copy; } + + /// + /// Add rhs to this column and return a reference to this column. + /// + column_t &operator+=(const column_t &rhs) { return *this = (*this + rhs); } + + /// + /// Subtrac rhs from this column and return a reference to this column. + /// + column_t &operator-=(const column_t &rhs) { return *this = (*this - rhs); } + + /// + /// Multiply this column by rhs and return a reference to this column. + /// + column_t &operator*=(const column_t &rhs) { return *this = (*this * rhs); } + + /// + /// Divide this column by rhs and return a reference to this column. + /// + column_t &operator/=(const column_t &rhs) { return *this = (*this / rhs); } + + /// + /// Mod this column by rhs and return a reference to this column. + /// + column_t &operator%=(const column_t &rhs) { return *this = (*this % rhs); } + + /// + /// Return true if other is to the right of this column. + /// + friend bool operator>(const column_t::index_t &left, const column_t &right) { return column_t(left) > right; } + + /// + /// Return true if other is to the right of or equal to this column. + /// + friend bool operator>=(const column_t::index_t &left, const column_t &right) { return column_t(left) >= right; } + + /// + /// Return true if other is to the left of this column. + /// + friend bool operator<(const column_t::index_t &left, const column_t &right) { return column_t(left) < right; } + + /// + /// Return true if other is to the left of or equal to this column. + /// + friend bool operator<=(const column_t::index_t &left, const column_t &right) { return column_t(left) <= right; } + + /// + /// Swap the columns that left and right refer to. + /// + friend void swap(column_t &left, column_t &right) + { + using std::swap; + swap(left.index, right.index); + } + + /// + /// Internal numeric value of this column index. + /// + index_t index; +}; + +/// +/// Functor for hashing a cell reference. +/// Allows for use of std::unordered_set and similar. +/// +struct column_hash +{ + std::size_t operator()(const column_t &k) const; +}; + +} // namespace xlnt + +namespace std { + +template <> +struct hash +{ + size_t operator()(const xlnt::column_t &k) const + { + return hasher(k); + } + + xlnt::column_hash hasher; +}; + +} // namespace std diff --git a/include/xlnt/config.hpp b/include/xlnt/config.hpp index 966180d1..49cc709a 100644 --- a/include/xlnt/config.hpp +++ b/include/xlnt/config.hpp @@ -44,4 +44,5 @@ enum class limit_style /// See limit_style for more information. /// const limit_style LimitStyle = limit_style::openpyxl; + } diff --git a/include/xlnt/utils/exceptions.hpp b/include/xlnt/utils/exceptions.hpp index c44c8e73..0b077292 100644 --- a/include/xlnt/utils/exceptions.hpp +++ b/include/xlnt/utils/exceptions.hpp @@ -35,7 +35,7 @@ namespace xlnt { class cell_coordinates_exception : public std::runtime_error { public: - cell_coordinates_exception(row_t row, column_t column); + cell_coordinates_exception(column_t column, row_t row); cell_coordinates_exception(const std::string &coord_string); }; diff --git a/include/xlnt/worksheet/range_reference.hpp b/include/xlnt/worksheet/range_reference.hpp index 91360d93..d6379651 100644 --- a/include/xlnt/worksheet/range_reference.hpp +++ b/include/xlnt/worksheet/range_reference.hpp @@ -42,8 +42,11 @@ class range_reference range_reference(column_t column_index_start, row_t row_index_start, column_t column_index_end, row_t row_index_end); bool is_single_cell() const; - column_t get_width() const; - row_t get_height() const; + + std::size_t get_width() const; + + std::size_t get_height() const; + cell_reference get_top_left() const { return top_left_; diff --git a/source/cell/cell.cpp b/source/cell/cell.cpp index d9c156b7..72430c0d 100644 --- a/source/cell/cell.cpp +++ b/source/cell/cell.cpp @@ -992,9 +992,9 @@ row_t cell::get_row() const return d_->row_; } -std::string cell::get_column() const +column_t cell::get_column() const { - return cell_reference::column_string_from_index(d_->column_); + return d_->column_; } void cell::set_merged(bool merged) @@ -1170,7 +1170,7 @@ void cell::set_error(const std::string &error) d_->type_ = type::error; } -cell cell::offset(column_t column, row_t row) +cell cell::offset(int column, int row) { return get_parent().get_cell(cell_reference(d_->column_ + column, d_->row_ + row)); } diff --git a/source/cell/cell_reference.cpp b/source/cell/cell_reference.cpp index beed27b9..b59a91ad 100644 --- a/source/cell/cell_reference.cpp +++ b/source/cell/cell_reference.cpp @@ -10,7 +10,7 @@ namespace xlnt { std::size_t cell_reference_hash::operator()(const cell_reference &k) const { - return k.get_row() * constants::MaxColumn + k.get_column_index(); + return k.get_row() * constants::MaxColumn().index + k.get_column_index().index; } cell_reference &cell_reference::make_absolute(bool absolute_column, bool absolute_row) @@ -39,14 +39,14 @@ cell_reference::cell_reference(const char *reference_string) } cell_reference::cell_reference(const std::string &column, row_t row) - : cell_reference(column_index_from_string(column), row) + : cell_reference(column_t(column), row) { } cell_reference::cell_reference(column_t column_index, row_t row) - : column_(column_index), row_(row), absolute_column_(false), absolute_row_(false) + : column_(column_index), row_(row), absolute_row_(false), absolute_column_(false) { - if (row_ == 0 || row_ >= constants::MaxRow || column_ == 0 || column_ >= constants::MaxColumn) + if (row_ == 0 || !(row_ <= constants::MaxRow()) || column_ == 0 || !(column_ <= constants::MaxColumn())) { throw cell_coordinates_exception(column_, row_); } @@ -66,7 +66,7 @@ std::string cell_reference::to_string() const string_representation.append("$"); } - string_representation.append(column_string_from_index(column_)); + string_representation.append(column_.column_string()); if (absolute_row_) { @@ -161,7 +161,7 @@ std::pair cell_reference::split_reference(const std::string cell_reference cell_reference::make_offset(int column_offset, int row_offset) const { //TODO: check for overflow/underflow - return cell_reference(static_cast(static_cast(column_) + column_offset), + return cell_reference(static_cast(static_cast(column_.index) + column_offset), static_cast(static_cast(row_) + row_offset)); } @@ -173,66 +173,6 @@ bool cell_reference::operator==(const cell_reference &comparand) const absolute_row_ == comparand.absolute_row_; } -column_t cell_reference::column_index_from_string(const std::string &column_string) -{ - if (column_string.length() > 3 || column_string.empty()) - { - throw column_string_index_exception(); - } - - column_t column_index = 0; - int place = 1; - - for (int i = static_cast(column_string.length()) - 1; i >= 0; i--) - { - if (!std::isalpha(column_string[static_cast(i)], std::locale::classic())) - { - throw column_string_index_exception(); - } - - column_index += static_cast( - (std::toupper(column_string[static_cast(i)], std::locale::classic()) - 'A' + 1) * place); - place *= 26; - } - - return column_index; -} - -// Convert a column number into a column letter (3 -> 'C') -// Right shift the column col_idx by 26 to find column letters in reverse -// order.These numbers are 1 - based, and can be converted to ASCII -// ordinals by adding 64. -std::string cell_reference::column_string_from_index(column_t column_index) -{ - // these indicies corrospond to A->ZZZ and include all allowed - // columns - if (column_index < 1 || column_index > constants::MaxColumn) - { - // auto msg = "Column index out of bounds: " + std::to_string(column_index); - throw column_string_index_exception(); - } - - int temp = static_cast(column_index); - std::string column_letter = ""; - - while (temp > 0) - { - int quotient = temp / 26, remainder = temp % 26; - - // check for exact division and borrow if needed - if (remainder == 0) - { - quotient -= 1; - remainder = 26; - } - - column_letter = std::string(1, char(remainder + 64)) + column_letter; - temp = quotient; - } - - return column_letter; -} - bool cell_reference::operator<(const cell_reference &other) { if (row_ != other.row_) diff --git a/source/cell/types.cpp b/source/cell/types.cpp new file mode 100644 index 00000000..4e211839 --- /dev/null +++ b/source/cell/types.cpp @@ -0,0 +1,77 @@ +#include + +#include +#include + +#include + +namespace xlnt { + +column_t::index_t column_t::column_index_from_string(const std::string &column_string) +{ + if (column_string.length() > 3 || column_string.empty()) + { + throw column_string_index_exception(); + } + + column_t::index_t column_index = 0; + int place = 1; + + for (int i = static_cast(column_string.length()) - 1; i >= 0; i--) + { + if (!std::isalpha(column_string[static_cast(i)], std::locale::classic())) + { + throw column_string_index_exception(); + } + + auto char_index = std::toupper(column_string[static_cast(i)], std::locale::classic()) - 'A'; + + column_index += static_cast((char_index + 1) * place); + place *= 26; + } + + return column_index; +} + +// Convert a column number into a column letter (3 -> 'C') +// Right shift the column col_idx by 26 to find column letters in reverse +// order.These numbers are 1 - based, and can be converted to ASCII +// ordinals by adding 64. +std::string column_t::column_string_from_index(column_t::index_t column_index) +{ + // these indicies corrospond to A->ZZZ and include all allowed + // columns + if (column_index < constants::MinColumn() || column_index > constants::MaxColumn()) + { + // auto msg = "Column index out of bounds: " + std::to_string(column_index); + throw column_string_index_exception(); + } + + int temp = static_cast(column_index); + std::string column_letter = ""; + + while (temp > 0) + { + int quotient = temp / 26, remainder = temp % 26; + + // check for exact division and borrow if needed + if (remainder == 0) + { + quotient -= 1; + remainder = 26; + } + + column_letter = std::string(1, char(remainder + 64)) + column_letter; + temp = quotient; + } + + return column_letter; +} + +std::size_t column_hash::operator()(const column_t &k) const +{ + static std::hash hasher; + return hasher(k.index); +} + +} // namespace xlnt diff --git a/source/detail/cell_impl.cpp b/source/detail/cell_impl.cpp index 81dfe8bc..7da4131a 100644 --- a/source/detail/cell_impl.cpp +++ b/source/detail/cell_impl.cpp @@ -6,7 +6,7 @@ namespace xlnt { namespace detail { -cell_impl::cell_impl() : cell_impl(1, 1) +cell_impl::cell_impl() : cell_impl(column_t(1), 1) { } diff --git a/source/detail/constants.cpp b/source/detail/constants.cpp index c5a61b2b..6d8e9a16 100644 --- a/source/detail/constants.cpp +++ b/source/detail/constants.cpp @@ -6,11 +6,40 @@ namespace xlnt { -const row_t constants::MinRow = 1; -const row_t constants::MaxRow = LimitStyle == limit_style::excel ? (1u << 20) : UINT32_MAX; -const column_t constants::MinColumn = 1; -const column_t constants::MaxColumn = - LimitStyle == limit_style::excel ? (1u << 14) : LimitStyle == limit_style::openpyxl ? 18278 : UINT32_MAX; +const row_t constants::MinRow() +{ + return 1; +} + +const row_t constants::MaxRow() +{ + if(LimitStyle == limit_style::excel) + { + return 1u << 20; + } + + return std::numeric_limits::max(); +} + +const column_t constants::MinColumn() +{ + return column_t(1); +} + +const column_t constants::MaxColumn() +{ + if(LimitStyle == limit_style::excel) + { + return column_t(1u << 14); + } + + if(LimitStyle == limit_style::openpyxl) + { + return column_t(18278); + } + + return column_t(std::numeric_limits::max()); +} // constants const std::string constants::PackageProps() { return "docProps"; } diff --git a/source/detail/constants.hpp b/source/detail/constants.hpp index 2ce387ac..9c1676c6 100644 --- a/source/detail/constants.hpp +++ b/source/detail/constants.hpp @@ -9,10 +9,10 @@ namespace xlnt { struct constants { - static const row_t MinRow; - static const row_t MaxRow; - static const column_t MinColumn; - static const column_t MaxColumn; + static const row_t MinRow(); + static const row_t MaxRow(); + static const column_t MinColumn(); + static const column_t MaxColumn(); // constants static const std::string PackageProps(); diff --git a/source/serialization/worksheet_serializer.cpp b/source/serialization/worksheet_serializer.cpp index 68bc8b98..a1a34ba9 100644 --- a/source/serialization/worksheet_serializer.cpp +++ b/source/serialization/worksheet_serializer.cpp @@ -96,7 +96,7 @@ bool worksheet_serializer::read_worksheet(const xml_document &xml) for (column_t i = min_column; i <= max_column; i++) { - std::string address = xlnt::cell_reference::column_string_from_index(i) + std::to_string(row_index); + std::string address = i.column_string() + std::to_string(row_index); xml_node cell_node; bool cell_found = false; @@ -253,7 +253,7 @@ xml_document worksheet_serializer::write_worksheet() const if (sheet_.get_frozen_panes().get_column_index() > 1) { - pane_node.add_attribute("xSplit", std::to_string(sheet_.get_frozen_panes().get_column_index() - 1)); + pane_node.add_attribute("xSplit", std::to_string(sheet_.get_frozen_panes().get_column_index().index - 1)); active_pane = "topRight"; } @@ -329,8 +329,8 @@ xml_document worksheet_serializer::write_worksheet() const auto col_node = cols_node.add_child("col"); - col_node.add_attribute("min", std::to_string(column)); - col_node.add_attribute("max", std::to_string(column)); + col_node.add_attribute("min", std::to_string(column.index)); + col_node.add_attribute("max", std::to_string(column.index)); col_node.add_attribute("width", std::to_string(props.width)); col_node.add_attribute("style", std::to_string(props.style)); col_node.add_attribute("customWidth", props.custom ? "1" : "0"); @@ -350,8 +350,8 @@ xml_document worksheet_serializer::write_worksheet() const for (auto cell : row) { - min = std::min(min, cell_reference::column_index_from_string(cell.get_column())); - max = std::max(max, cell_reference::column_index_from_string(cell.get_column())); + min = std::min(min, cell.get_column().index); + max = std::max(max, cell.get_column().index); if (!cell.garbage_collectible()) { diff --git a/source/utils/exceptions.cpp b/source/utils/exceptions.cpp index 6693d10a..27ce002b 100644 --- a/source/utils/exceptions.cpp +++ b/source/utils/exceptions.cpp @@ -29,14 +29,14 @@ invalid_file_exception::invalid_file_exception(const std::string &filename) { } -cell_coordinates_exception::cell_coordinates_exception(row_t row, column_t column) - : std::runtime_error(std::string("bad cell coordinates: (") + std::to_string(row) + "," + std::to_string(column) + +cell_coordinates_exception::cell_coordinates_exception(column_t column, row_t row) + : std::runtime_error(std::string("bad cell coordinates: (") + std::to_string(column.index) + ", " + std::to_string(row) + ")") { } cell_coordinates_exception::cell_coordinates_exception(const std::string &coord_string) - : std::runtime_error(std::string("bad cell coordinates: (") + coord_string + ")") + : std::runtime_error(std::string("bad cell coordinates: (") + (coord_string.empty() ? "" : coord_string) + ")") { } diff --git a/source/worksheet/range.cpp b/source/worksheet/range.cpp index c9a4fc1d..f4570a1d 100644 --- a/source/worksheet/range.cpp +++ b/source/worksheet/range.cpp @@ -73,7 +73,7 @@ cell cell_vector::front() { if (order_ == major_order::row) { - return get_cell(ref_.get_top_left().get_column_index()); + return get_cell(ref_.get_top_left().get_column().index); } return get_cell(ref_.get_top_left().get_row()); @@ -83,7 +83,7 @@ cell cell_vector::back() { if (order_ == major_order::row) { - return get_cell(ref_.get_bottom_right().get_column_index()); + return get_cell(ref_.get_bottom_right().get_column().index); } return get_cell(ref_.get_top_left().get_row()); @@ -125,7 +125,7 @@ std::size_t range::length() const return ref_.get_bottom_right().get_row() - ref_.get_top_left().get_row() + 1; } - return ref_.get_bottom_right().get_column_index() - ref_.get_top_left().get_column_index() + 1; + return (ref_.get_bottom_right().get_column() - ref_.get_top_left().get_column()).index + 1; } bool range::operator==(const range &comparand) const @@ -147,9 +147,9 @@ cell_vector range::get_vector(std::size_t vector_index) } range_reference reference( - static_cast(static_cast(ref_.get_top_left().get_column_index()) + vector_index), + static_cast(static_cast(ref_.get_top_left().get_column().index) + vector_index), ref_.get_top_left().get_row(), - static_cast(static_cast(ref_.get_top_left().get_column_index()) + vector_index), + static_cast(static_cast(ref_.get_top_left().get_column().index) + vector_index), ref_.get_bottom_right().get_row()); return cell_vector(ws_, reference, order_); @@ -164,7 +164,7 @@ bool range::contains(const cell_reference &ref) cell range::get_cell(const cell_reference &ref) { - return (*this)[ref.get_row()][ref.get_column_index()]; + return (*this)[ref.get_row()][ref.get_column().index]; } range::iterator range::begin() diff --git a/source/worksheet/range_reference.cpp b/source/worksheet/range_reference.cpp index 728396cd..007bdfbb 100644 --- a/source/worksheet/range_reference.cpp +++ b/source/worksheet/range_reference.cpp @@ -53,14 +53,14 @@ range_reference range_reference::make_offset(int column_offset, int row_offset) bottom_right_.make_offset(column_offset, row_offset)); } -row_t range_reference::get_height() const +std::size_t range_reference::get_height() const { return bottom_right_.get_row() - top_left_.get_row(); } -column_t range_reference::get_width() const +std::size_t range_reference::get_width() const { - return bottom_right_.get_column_index() - top_left_.get_column_index(); + return (bottom_right_.get_column() - top_left_.get_column()).index; } bool range_reference::is_single_cell() const diff --git a/source/worksheet/tests/test_worksheet.hpp b/source/worksheet/tests/test_worksheet.hpp index db268384..3e809da5 100644 --- a/source/worksheet/tests/test_worksheet.hpp +++ b/source/worksheet/tests/test_worksheet.hpp @@ -62,8 +62,8 @@ public: void test_iter_rows_1() { - row_t row = 0; - column_t column = 0; + std::size_t row = 0; + std::size_t column = 0; std::string coordinate = "A1"; xlnt::worksheet ws(wb_); diff --git a/source/worksheet/worksheet.cpp b/source/worksheet/worksheet.cpp index b56f2d76..0ef082c2 100644 --- a/source/worksheet/worksheet.cpp +++ b/source/worksheet/worksheet.cpp @@ -14,6 +14,7 @@ #include #include +#include #include namespace xlnt { @@ -249,16 +250,16 @@ column_t worksheet::get_lowest_column() const { if (d_->cell_map_.empty()) { - return 1; + return constants::MinColumn(); } - column_t lowest = std::numeric_limits::max(); + column_t lowest = constants::MaxColumn(); for (auto &row : d_->cell_map_) { for (auto &c : row.second) { - lowest = std::min(lowest, (column_t)c.first); + lowest = std::min(lowest, c.first); } } @@ -269,14 +270,14 @@ row_t worksheet::get_lowest_row() const { if (d_->cell_map_.empty()) { - return 1; + return constants::MinRow(); } - row_t lowest = std::numeric_limits::max(); + row_t lowest = constants::MaxRow(); for (auto &row : d_->cell_map_) { - lowest = std::min(lowest, (row_t)row.first); + lowest = std::min(lowest, row.first); } return lowest; @@ -284,11 +285,11 @@ row_t worksheet::get_lowest_row() const row_t worksheet::get_highest_row() const { - row_t highest = 1; + row_t highest = constants::MinRow(); for (auto &row : d_->cell_map_) { - highest = std::max(highest, (row_t)row.first); + highest = std::max(highest, row.first); } return highest; @@ -296,13 +297,13 @@ row_t worksheet::get_highest_row() const column_t worksheet::get_highest_column() const { - column_t highest = 1; + column_t highest = constants::MinColumn(); for (auto &row : d_->cell_map_) { for (auto &c : row.second) { - highest = std::max(highest, (column_t)c.first); + highest = std::max(highest, c.first); } }