Merge remote-tracking branch 'upstream/dev' into dev-test-suite-improvements

# Conflicts:
#	tests/workbook/workbook_test_suite.cpp
This commit is contained in:
Crzyrndm 2018-07-13 11:38:56 +12:00
commit 54b1affd1e
48 changed files with 810 additions and 154 deletions

View File

@ -240,6 +240,11 @@ public:
/// </summary>
column_t column() const;
/// <summary>
/// Returns the numeric index (A == 1) of the column of this cell.
/// </summary>
column_t::index_t column_index() const;
/// <summary>
/// Returns the row of this cell.
/// </summary>

View File

@ -46,7 +46,6 @@ class XLNT_API ext_list
public:
struct ext
{
public:
ext(xml::parser &parser, const std::string& ns);
ext(const uri& ID, const std::string& serialised);
void serialise(xml::serializer &serialiser, const std::string& ns);
@ -66,7 +65,14 @@ public:
const std::vector<ext> &extensions() const;
bool operator==(const ext_list& rhs) const;
private:
std::vector<ext> extensions_;
};
inline bool operator==(const ext_list::ext& lhs, const ext_list::ext& rhs)
{
return lhs.extension_ID_ == rhs.extension_ID_
&& lhs.serialised_value_ == rhs.serialised_value_;
}
} // namespace xlnt

View File

@ -172,6 +172,8 @@ public:
/// </summary>
void unregister_override_type(const path &part);
bool operator==(const manifest &other) const;
private:
/// <summary>
/// Returns the lowest rId for the given part that hasn't already been registered.

View File

@ -53,6 +53,11 @@ public:
static condition text_contains(const std::string &start);
static condition text_does_not_contain(const std::string &start);
bool operator==(const condition& rhs) const
{
return text_comparand_ == rhs.text_comparand_;
}
private:
friend class detail::xlsx_producer;

View File

@ -125,8 +125,14 @@ public:
/// </summary>
bool operator==(const optional<T> &other) const
{
return has_value_ == other.has_value_
&& (!has_value_ || value_ == other.value_);
if (has_value_ != other.has_value_) {
return false;
}
if (!has_value_)
{
return true;
}
return value_ == other.value_;
}
private:

View File

@ -162,6 +162,8 @@ public:
/// </summary>
type value_type() const;
bool operator==(const variant &rhs) const;
private:
type type_;
std::vector<variant> vector_value_;

View File

@ -46,4 +46,10 @@ public:
bool concurrent_calc;
};
inline bool operator==(const calculation_properties &lhs, const calculation_properties &rhs)
{
return lhs.calc_id == rhs.calc_id
&& lhs.concurrent_calc == rhs.concurrent_calc;
}
} // namespace xlnt

View File

@ -76,6 +76,8 @@ public:
/// </summary>
named_range &operator=(const named_range &other);
bool operator==(const named_range &rhs) const;
private:
/// <summary>
/// The name of this named range.

View File

@ -33,6 +33,11 @@ namespace xlnt {
/// </summary>
class XLNT_API theme
{
public:
bool operator==(const theme&) const
{
return true;
}
};
} // namespace xlnt

View File

@ -130,6 +130,26 @@ public:
/// </summary>
workbook();
/// <summary>
/// load the xlsx file at path
/// </summary>
workbook(const xlnt::path &file);
/// <summary>
/// load the encrpyted xlsx file at path
/// </summary>
workbook(const xlnt::path &file, const std::string& password);
/// <summary>
/// construct the workbook from any data stream where the data is the binary form of a workbook
/// </summary>
workbook(std::istream & data);
/// <summary>
/// construct the workbook from any data stream where the data is the binary form of an encrypted workbook
/// </summary>
workbook(std::istream &data, const std::string& password);
/// <summary>
/// Move constructor. Constructs a workbook from existing workbook, other.
/// </summary>

View File

@ -102,4 +102,17 @@ public:
optional<int> y_window;
};
inline bool operator==(const workbook_view &lhs, const workbook_view &rhs)
{
return lhs.active_tab == rhs.active_tab
&& lhs.auto_filter_date_grouping == rhs.auto_filter_date_grouping
&& lhs.first_sheet == rhs.first_sheet
&& lhs.minimized == rhs.minimized
&& lhs.show_horizontal_scroll == rhs.show_horizontal_scroll
&& lhs.show_sheet_tabs == rhs.show_sheet_tabs
&& lhs.show_vertical_scroll == rhs.show_vertical_scroll
&& lhs.tab_ratio == rhs.tab_ratio
&& lhs.visible == rhs.visible;
}
} // namespace xlnt

View File

@ -37,18 +37,22 @@ class worksheet;
// because one needs to point at a const workbook and the other needs
// to point at a non-const workbook stored as a member variable, respectively.
/// <summary>
/// Alias the parent class of this iterator to increase clarity.
/// </summary>
using ws_iter_type = std::iterator<std::bidirectional_iterator_tag,
worksheet, std::ptrdiff_t, worksheet *, worksheet>;
/// <summary>
/// An iterator which is used to iterate over the worksheets in a workbook.
/// </summary>
class XLNT_API worksheet_iterator : public ws_iter_type
class XLNT_API worksheet_iterator
{
public:
/// <summary>
/// iterator tags required for use with standard algorithms and adapters
/// </summary>
using iterator_category = std::bidirectional_iterator_tag;
using value_type = worksheet;
using difference_type = std::ptrdiff_t;
using pointer = worksheet *;
using reference = worksheet; // intentionally value
/// <summary>
/// Constructs a worksheet iterator from a workbook and sheet index.
/// </summary>
@ -57,19 +61,41 @@ public:
/// <summary>
/// Copy constructs a worksheet iterator from another iterator.
/// </summary>
worksheet_iterator(const worksheet_iterator &);
worksheet_iterator(const worksheet_iterator &) = default;
/// <summary>
/// Assigns the iterator so that it points to the same worksheet in the same workbook.
/// Copy assigns the iterator so that it points to the same worksheet in the same workbook.
/// </summary>
worksheet_iterator &operator=(const worksheet_iterator &);
worksheet_iterator &operator=(const worksheet_iterator &) = default;
/// <summary>
/// Move constructs a worksheet iterator from a temporary iterator.
/// </summary>
worksheet_iterator(worksheet_iterator &&) = default;
/// <summary>
/// Move assign the iterator from a temporary iterator
/// </summary>
worksheet_iterator &operator=(worksheet_iterator &&) = default;
/// <summary>
/// Default destructor
/// </summary>
~worksheet_iterator() = default;
/// <summary>
/// Dereferences the iterator to return the worksheet it is pointing to.
/// If the iterator points to one-past-the-end of the workbook, an invalid_parameter
/// exception will be thrown.
/// </summary>
worksheet operator*();
reference operator*();
/// <summary>
/// Dereferences the iterator to return the worksheet it is pointing to.
/// If the iterator points to one-past-the-end of the workbook, an invalid_parameter
/// exception will be thrown.
/// </summary>
const reference operator*() const;
/// <summary>
/// Returns true if this iterator points to the same worksheet as comparand.
@ -93,11 +119,23 @@ public:
/// </summary>
worksheet_iterator &operator++();
/// <summary>
/// Post-decrement the iterator's internal workseet index. Returns a copy of the
/// iterator as it was before being incremented.
/// </summary>
worksheet_iterator operator--(int);
/// <summary>
/// Pre-decrement the iterator's internal workseet index. Returns a refernce
/// to the same iterator.
/// </summary>
worksheet_iterator &operator--();
private:
/// <summary>
/// The target workbook of this iterator.
/// </summary>
workbook &wb_;
workbook *wb_;
/// <summary>
/// The index of the worksheet in wb_ this iterator is currently pointing to.
@ -106,18 +144,21 @@ private:
};
/// <summary>
/// Alias the parent class of this iterator to increase clarity.
/// </summary>
using c_ws_iter_type = std::iterator<std::bidirectional_iterator_tag,
const worksheet, std::ptrdiff_t, const worksheet *, const worksheet>;
/// <summary>
/// An iterator which is used to iterate over the worksheets in a const workbook.
/// </summary>
class XLNT_API const_worksheet_iterator : public c_ws_iter_type
class XLNT_API const_worksheet_iterator
{
public:
/// <summary>
/// iterator tags required for use with standard algorithms and adapters
/// </summary>
using iterator_category = std::bidirectional_iterator_tag;
using value_type = const worksheet;
using difference_type = std::ptrdiff_t;
using pointer = const worksheet *;
using reference = const worksheet; // intentionally value
/// <summary>
/// Constructs a worksheet iterator from a workbook and sheet index.
/// </summary>
@ -126,19 +167,34 @@ public:
/// <summary>
/// Copy constructs a worksheet iterator from another iterator.
/// </summary>
const_worksheet_iterator(const const_worksheet_iterator &);
const_worksheet_iterator(const const_worksheet_iterator &) = default;
/// <summary>
/// Assigns the iterator so that it points to the same worksheet in the same workbook.
/// Copy assigns the iterator so that it points to the same worksheet in the same workbook.
/// </summary>
const_worksheet_iterator &operator=(const const_worksheet_iterator &);
const_worksheet_iterator &operator=(const const_worksheet_iterator &) = default;
/// <summary>
/// Move constructs a worksheet iterator from a temporary iterator.
/// </summary>
const_worksheet_iterator(const_worksheet_iterator &&) = default;
/// <summary>
/// Move assigns the iterator from a temporary iterator
/// </summary>
const_worksheet_iterator &operator=(const_worksheet_iterator &&) = default;
/// <summary>
/// Default destructor
/// </summary>
~const_worksheet_iterator() = default;
/// <summary>
/// Dereferences the iterator to return the worksheet it is pointing to.
/// If the iterator points to one-past-the-end of the workbook, an invalid_parameter
/// exception will be thrown.
/// </summary>
const worksheet operator*();
const reference operator*() const;
/// <summary>
/// Returns true if this iterator points to the same worksheet as comparand.
@ -162,11 +218,23 @@ public:
/// </summary>
const_worksheet_iterator &operator++();
/// <summary>
/// Post-decrement the iterator's internal workseet index. Returns a copy of the
/// iterator as it was before being incremented.
/// </summary>
const_worksheet_iterator operator--(int);
/// <summary>
/// Pre-decrement the iterator's internal workseet index. Returns a refernce
/// to the same iterator.
/// </summary>
const_worksheet_iterator &operator--();
private:
/// <summary>
/// The target workbook of this iterator.
/// </summary>
const workbook &wb_;
const workbook *wb_;
/// <summary>
/// The index of the worksheet in wb_ this iterator is currently pointing to.

View File

@ -40,18 +40,21 @@ class cell;
class cell_reference;
class range_reference;
/// <summary>
/// Alias the parent class of this iterator to increase clarity.
/// </summary>
using c_iter_type = std::iterator<std::bidirectional_iterator_tag,
cell, std::ptrdiff_t, cell *, cell>;
/// <summary>
/// A cell iterator iterates over a 1D range by row or by column.
/// </summary>
class XLNT_API cell_iterator : public c_iter_type
class XLNT_API cell_iterator
{
public:
/// <summary>
/// iterator tags required for use with standard algorithms and adapters
/// </summary>
using iterator_category = std::bidirectional_iterator_tag;
using value_type = cell;
using difference_type = std::ptrdiff_t;
using pointer = cell *;
using reference = cell; // intentionally value
/// <summary>
/// Constructs a cell_iterator from a worksheet, range, and iteration settings.
/// </summary>
@ -61,17 +64,38 @@ public:
/// <summary>
/// Constructs a cell_iterator as a copy of an existing cell_iterator.
/// </summary>
cell_iterator(const cell_iterator &other);
cell_iterator(const cell_iterator &) = default;
/// <summary>
/// Assigns this iterator to match the data in rhs.
/// </summary>
cell_iterator &operator=(const cell_iterator &rhs) = default;
cell_iterator &operator=(const cell_iterator &) = default;
/// <summary>
/// Constructs a cell_iterator by moving from a cell_iterator temporary
/// </summary>
cell_iterator(cell_iterator &&) = default;
/// <summary>
/// Assigns this iterator to from a cell_iterator temporary
/// </summary>
cell_iterator &operator=(cell_iterator &&) = default;
/// <summary>
/// destructor for const_cell_iterator
/// </summary>
~cell_iterator() = default;
/// <summary>
/// Dereferences this iterator to return the cell it points to.
/// </summary>
cell operator*();
reference operator*();
/// <summary>
/// Dereferences this iterator to return the cell it points to.
/// </summary>
const reference operator*() const;
/// <summary>
/// Returns true if this iterator is equivalent to other.
@ -135,7 +159,7 @@ private:
/// If true, cells that don't exist in the worksheet will be skipped during iteration.
/// </summary>
bool skip_null_;
/// <summary>
/// If true, when on the last column, the cursor will continue to the next row
/// (and vice versa when iterating in column-major order) until reaching the
@ -144,18 +168,21 @@ private:
bool wrap_;
};
/// <summary>
/// Alias the parent class of this iterator to increase clarity.
/// </summary>
using cc_iter_type = std::iterator<std::bidirectional_iterator_tag,
const cell, std::ptrdiff_t, const cell *, const cell>;
/// <summary>
/// A cell iterator iterates over a 1D range by row or by column.
/// </summary>
class XLNT_API const_cell_iterator : public cc_iter_type
class XLNT_API const_cell_iterator
{
public:
/// <summary>
/// iterator tags required for use with standard algorithms and adapters
/// </summary>
using iterator_category = std::bidirectional_iterator_tag;
using value_type = const cell;
using difference_type = std::ptrdiff_t;
using pointer = const cell *;
using reference = const cell; // intentionally value
/// <summary>
/// Constructs a cell_iterator from a worksheet, range, and iteration settings.
/// </summary>
@ -163,19 +190,34 @@ public:
const range_reference &limits, major_order order, bool skip_null, bool wrap);
/// <summary>
/// Constructs a cell_iterator as a copy of an existing cell_iterator.
/// Constructs a const_cell_iterator as a copy of an existing cell_iterator.
/// </summary>
const_cell_iterator(const const_cell_iterator &other);
const_cell_iterator(const const_cell_iterator &) = default;
/// <summary>
/// Assigns this iterator to match the data in rhs.
/// </summary>
const_cell_iterator &operator=(const const_cell_iterator &) = default;
/// <summary>
/// Constructs a const_cell_iterator by moving from a const_cell_iterator temporary
/// </summary>
const_cell_iterator(const_cell_iterator &&) = default;
/// <summary>
/// Assigns this iterator to from a const_cell_iterator temporary
/// </summary>
const_cell_iterator &operator=(const_cell_iterator &&) = default;
/// <summary>
/// destructor for const_cell_iterator
/// </summary>
~const_cell_iterator() = default;
/// <summary>
/// Dereferences this iterator to return the cell it points to.
/// </summary>
const cell operator*() const;
const reference operator*() const;
/// <summary>
/// Returns true if this iterator is equivalent to other.

View File

@ -63,4 +63,13 @@ public:
bool hidden = false;
};
inline bool operator==(const column_properties &lhs, const column_properties &rhs)
{
return lhs.width == rhs.width
&& lhs.custom_width == rhs.custom_width
&& lhs.style == rhs.style
&& lhs.best_fit == rhs.best_fit
&& lhs.hidden == rhs.hidden;
}
} // namespace xlnt

View File

@ -312,6 +312,8 @@ public:
/// </summary>
rich_text even_footer(location where) const;
bool operator==(const header_footer &rhs) const;
private:
bool align_with_margins_ = false;
bool different_odd_even_ = false;

View File

@ -99,6 +99,8 @@ public:
/// </summary>
void footer(double footer);
bool operator==(const page_margins &rhs) const;
private:
/// <summary>
/// The top margin

View File

@ -172,6 +172,8 @@ public:
/// </summary>
xlnt::optional<std::size_t> vertical_dpi_;
bool operator==(const page_setup &rhs) const;
private:
/// <summary>
/// The break

View File

@ -143,6 +143,8 @@ public:
/// </summary>
static align alignment_from_string(const std::string &str);
bool operator==(const phonetic_pr &rhs) const;
private:
/// <summary>
/// zero based index into style sheet font record.

View File

@ -55,4 +55,13 @@ struct XLNT_API print_options
/// </summary>
optional<bool> vertical_centered;
};
inline bool operator==(const print_options& lhs, const print_options &rhs)
{
return lhs.grid_lines_set == rhs.grid_lines_set
&& lhs.horizontal_centered == rhs.horizontal_centered
&& lhs.print_grid_lines == rhs.print_grid_lines
&& lhs.print_headings == rhs.print_headings
&& lhs.vertical_centered == rhs.vertical_centered;
}
} // namespace xlnt

View File

@ -117,6 +117,11 @@ public:
/// </summary>
const class cell cell(const cell_reference &ref) const;
/// <summary>
/// The worksheet this range targets
/// </summary>
const worksheet & target_worksheet() const;
/// <summary>
/// Returns the reference defining the bounds of this range.
/// </summary>

View File

@ -35,19 +35,22 @@ namespace xlnt {
class cell_vector;
/// <summary>
/// Alias the parent class of this iterator to increase clarity.
/// </summary>
using r_iter_type = std::iterator<std::bidirectional_iterator_tag,
cell_vector, std::ptrdiff_t, cell_vector *, cell_vector>;
/// <summary>
/// An iterator used by worksheet and range for traversing
/// a 2D grid of cells by row/column then across that row/column.
/// </summary>
class XLNT_API range_iterator : public r_iter_type
class XLNT_API range_iterator
{
public:
/// <summary>
/// iterator tags required for use with standard algorithms and adapters
/// </summary>
using iterator_category = std::bidirectional_iterator_tag;
using value_type = cell_vector;
using difference_type = std::ptrdiff_t;
using pointer = cell_vector *;
using reference = cell_vector; // intentionally value
/// <summary>
/// Constructs a range iterator on a worksheet, cell pointing to the current
/// row or column, range bounds, an order, and whether or not to skip null column/rows.
@ -56,20 +59,40 @@ public:
const range_reference &bounds, major_order order, bool skip_null);
/// <summary>
/// Copy constructor.
/// Default copy constructor.
/// </summary>
range_iterator(const range_iterator &other);
/// <summary>
/// Dereference the iterator to return a column or row.
/// </summary>
cell_vector operator*() const;
range_iterator(const range_iterator &) = default;
/// <summary>
/// Default assignment operator.
/// </summary>
range_iterator &operator=(const range_iterator &) = default;
/// <summary>
/// Default move constructor.
/// </summary>
range_iterator(range_iterator &&) = default;
/// <summary>
/// Default move assignment operator.
/// </summary>
range_iterator &operator=(range_iterator &&) = default;
/// <summary>
/// Default destructor
/// </summary>
~range_iterator() = default;
/// <summary>
/// Dereference the iterator to return a column or row.
/// </summary>
reference operator*();
/// <summary>
/// Dereference the iterator to return a column or row.
/// </summary>
const reference operator*() const;
/// <summary>
/// Returns true if this iterator is equivalent to other.
/// </summary>
@ -127,19 +150,22 @@ private:
bool skip_null_;
};
/// <summary>
/// Alias the parent class of this iterator to increase clarity.
/// </summary>
using cr_iter_type = std::iterator<std::bidirectional_iterator_tag,
const cell_vector, std::ptrdiff_t, const cell_vector *, const cell_vector>;
/// <summary>
/// A const version of range_iterator which does not allow modification
/// to the dereferenced cell_vector.
/// </summary>
class XLNT_API const_range_iterator : public cr_iter_type
class XLNT_API const_range_iterator
{
public:
/// <summary>
/// this iterator meets the interface requirements of bidirection_iterator
/// </summary>
using iterator_category = std::bidirectional_iterator_tag;
using value_type = const cell_vector;
using difference_type = std::ptrdiff_t;
using pointer = const cell_vector *;
using reference = const cell_vector; // intentionally value
/// <summary>
/// Constructs a range iterator on a worksheet, cell pointing to the current
/// row or column, range bounds, an order, and whether or not to skip null column/rows.
@ -148,20 +174,35 @@ public:
const range_reference &bounds, major_order order, bool skip_null);
/// <summary>
/// Copy constructor.
/// Default copy constructor.
/// </summary>
const_range_iterator(const const_range_iterator &other);
/// <summary>
/// Dereferennce the iterator to return the current column/row.
/// </summary>
const cell_vector operator*() const;
const_range_iterator(const const_range_iterator &) = default;
/// <summary>
/// Default assignment operator.
/// </summary>
const_range_iterator &operator=(const const_range_iterator &) = default;
/// <summary>
/// Default move constructor.
/// </summary>
const_range_iterator(const_range_iterator &&) = default;
/// <summary>
/// Default move assignment operator.
/// </summary>
const_range_iterator &operator=(const_range_iterator &&) = default;
/// <summary>
/// Default destructor
/// </summary>
~const_range_iterator() = default;
/// <summary>
/// Dereferennce the iterator to return the current column/row.
/// </summary>
const reference operator*() const;
/// <summary>
/// Returns true if this iterator is equivalent to other.
/// </summary>

View File

@ -65,4 +65,14 @@ public:
optional<std::size_t> style;
};
inline bool operator==(const row_properties &lhs, const row_properties &rhs)
{
return lhs.height == rhs.height
&& lhs.dy_descent == rhs.dy_descent
&& lhs.custom_height == rhs.custom_height
&& lhs.hidden == rhs.hidden
&& lhs.custom_format == rhs.custom_format
&& lhs.style == rhs.style;
}
} // namespace xlnt

View File

@ -55,4 +55,12 @@ public:
optional<double> dy_descent;
};
inline bool operator==(const sheet_format_properties &lhs, const sheet_format_properties &rhs)
{
return lhs.base_col_width == rhs.base_col_width
&& lhs.default_column_width == rhs.default_column_width
&& lhs.default_row_height == rhs.default_row_height
&& lhs.dy_descent == rhs.dy_descent;
}
} // namespace xlnt

View File

@ -78,4 +78,17 @@ struct XLNT_API sheet_pr
/// </summary>
optional<bool> enable_format_condition_calculation;
};
inline bool operator==(const sheet_pr &lhs, const sheet_pr &rhs)
{
return lhs.sync_horizontal == rhs.sync_horizontal
&& lhs.sync_vertical == rhs.sync_vertical
&& lhs.sync_ref == rhs.sync_ref
&& lhs.transition_evaluation == rhs.transition_evaluation
&& lhs.transition_entry == rhs.transition_entry
&& lhs.published == rhs.published
&& lhs.code_name == rhs.code_name
&& lhs.filter_mode == rhs.filter_mode
&& lhs.enable_format_condition_calculation == rhs.enable_format_condition_calculation;
}
} // namespace xlnt

View File

@ -314,6 +314,11 @@ column_t cell::column() const
return d_->column_;
}
column_t::index_t cell::column_index() const
{
return d_->column_.index;
}
void cell::merged(bool merged)
{
d_->is_merged_ = merged;

View File

@ -61,5 +61,21 @@ struct cell_impl
optional<comment *> comment_;
};
inline bool operator==(const cell_impl &lhs, const cell_impl &rhs)
{
// not comparing parent
return lhs.type_ == rhs.type_
&& lhs.column_ == rhs.column_
&& lhs.row_ == rhs.row_
&& lhs.is_merged_ == rhs.is_merged_
&& lhs.value_text_ == rhs.value_text_
&& lhs.value_numeric_ == rhs.value_numeric_
&& lhs.formula_ == rhs.formula_
&& lhs.hyperlink_ == rhs.hyperlink_
// comparing pointers is unlikely to be what is wanted
/*&& lhs.format_ == rhs.format_
&& lhs.comment_ == rhs.comment_*/;
}
} // namespace detail
} // namespace xlnt

View File

@ -20,8 +20,21 @@ struct worksheet_impl;
struct conditional_format_impl
{
stylesheet *parent;
worksheet_impl *target_sheet;
bool operator==(const conditional_format_impl& rhs) const
{
// not comparing parent or target sheet
return target_range == rhs.target_range
&& priority == rhs.priority
&& differential_format_id == rhs.differential_format_id
&& when == rhs.when
&& border_id == rhs.border_id
&& fill_id == rhs.fill_id
&& font_id == rhs.font_id;
}
range_reference target_range;
worksheet_impl *target_sheet;
std::size_t priority;
std::size_t differential_format_id;

View File

@ -37,5 +37,12 @@ struct hyperlink_impl
std::string display;
};
inline bool operator==(const hyperlink_impl &lhs, const hyperlink_impl &rhs)
{
return lhs.relationship == rhs.relationship
&& lhs.tooltip == rhs.tooltip
&& lhs.display == rhs.display;
}
} // namespace detail
} // namespace xlnt

View File

@ -22,6 +22,30 @@ struct style_impl
{
stylesheet *parent;
bool operator==(const style_impl& rhs) const
{
return name == rhs.name
&& formatting_record_id == rhs.formatting_record_id
&& custom_builtin == rhs.custom_builtin
&& hidden_style == rhs.hidden_style
&& builtin_id == rhs.builtin_id
&& outline_style == rhs.outline_style
&& alignment_id == rhs.alignment_id
&& alignment_applied == rhs.alignment_applied
&& border_id == rhs.border_id
&& border_applied == rhs.border_applied
&& fill_id == rhs.fill_id
&& fill_applied == rhs.fill_applied
&& font_id == rhs.font_id
&& font_applied == rhs.font_applied
&& number_format_id == rhs.number_format_id
&& number_format_applied == number_format_applied
&& protection_id == rhs.protection_id
&& protection_applied == rhs.protection_applied
&& pivot_button_ == rhs.pivot_button_
&& quote_prefix_ == rhs.quote_prefix_;
}
std::string name;
std::size_t formatting_record_id;

View File

@ -527,6 +527,25 @@ struct stylesheet
}
workbook *parent;
bool operator==(const stylesheet& rhs) const
{
// no equality on parent as there is only 1 stylesheet per borkbook hence would always be false
return garbage_collection_enabled == rhs.garbage_collection_enabled
&& known_fonts_enabled == rhs.known_fonts_enabled
&& conditional_format_impls == rhs.conditional_format_impls
&& format_impls == rhs.format_impls
&& style_impls == rhs.style_impls
&& style_names == rhs.style_names
&& default_slicer_style == rhs.default_slicer_style
&& alignments == rhs.alignments
&& borders == rhs.borders
&& fills == rhs.fills
&& fonts == rhs.fonts
&& number_formats == rhs.number_formats
&& protections == rhs.protections
&& colors == rhs.colors;
}
bool garbage_collection_enabled = true;
bool known_fonts_enabled = false;

View File

@ -89,6 +89,30 @@ struct workbook_impl
return *this;
}
bool operator==(const workbook_impl &other)
{
return active_sheet_index_ == other.active_sheet_index_
&& worksheets_ == other.worksheets_
&& shared_strings_ == other.shared_strings_
&& stylesheet_ == other.stylesheet_
&& base_date_ == other.base_date_
&& title_ == other.title_
&& manifest_ == other.manifest_
&& theme_ == other.theme_
&& images_ == other.images_
&& core_properties_ == other.core_properties_
&& extended_properties_ == other.extended_properties_
&& custom_properties_ == other.custom_properties_
&& sheet_title_rel_id_map_ == other.sheet_title_rel_id_map_
&& view_ == other.view_
&& code_name_ == other.code_name_
&& file_version_ == other.file_version_
&& calculation_properties_ == other.calculation_properties_
&& abs_path_ == other.abs_path_
&& arch_id_flags_ == other.arch_id_flags_
&& extensions_ == other.extensions_;
}
optional<std::size_t> active_sheet_index_;
std::list<worksheet_impl> worksheets_;
@ -118,6 +142,14 @@ struct workbook_impl
std::size_t last_edited;
std::size_t lowest_edited;
std::size_t rup_build;
bool operator==(const file_version_t& rhs) const
{
return app_name == rhs.app_name
&& last_edited == rhs.last_edited
&& lowest_edited == rhs.lowest_edited
&& rup_build == rhs.rup_build;
}
};
optional<file_version_t> file_version_;

View File

@ -99,6 +99,33 @@ struct worksheet_impl
workbook *parent_;
bool operator==(const worksheet_impl& rhs) const
{
return id_ == rhs.id_
&& title_ == rhs.title_
&& format_properties_ == rhs.format_properties_
&& column_properties_ == rhs.column_properties_
&& row_properties_ == rhs.row_properties_
&& cell_map_ == rhs.cell_map_
&& page_setup_ == rhs.page_setup_
&& auto_filter_ == rhs.auto_filter_
&& page_margins_ == rhs.page_margins_
&& merged_cells_ == rhs.merged_cells_
&& named_ranges_ == rhs.named_ranges_
&& phonetic_properties_ == rhs.phonetic_properties_
&& header_footer_ == rhs.header_footer_
&& print_title_cols_ == rhs.print_title_cols_
&& print_title_rows_ == rhs.print_title_rows_
&& print_area_ == rhs.print_area_
&& views_ == rhs.views_
&& column_breaks_ == rhs.column_breaks_
&& row_breaks_ == rhs.row_breaks_
&& comments_ == rhs.comments_
&& print_options_ == rhs.print_options_
&& sheet_properties_ == rhs.sheet_properties_
&& extension_list_ == rhs.extension_list_;
}
std::size_t id_;
std::string title_;

View File

@ -864,11 +864,7 @@ void xlsx_producer::write_shared_string_table(const relationship & /*rel*/)
{
write_start_element(xmlns, "si");
write_start_element(xmlns, "t");
if (string.runs().front().preserve_space)
{
write_attribute(xml::qname(xmlns_xml, "space"), "preserve");
}
write_characters(string.plain_text(), has_trailing_whitespace(string.plain_text()));
write_characters(string.plain_text(),string.runs().front().preserve_space);
write_end_element(xmlns, "t");
write_end_element(xmlns, "si");

View File

@ -137,4 +137,9 @@ const std::vector<ext_list::ext> &ext_list::extensions() const
return extensions_;
}
bool ext_list::operator==(const ext_list &rhs) const
{
return extensions_ == rhs.extensions_;
}
}

View File

@ -337,4 +337,11 @@ std::string manifest::override_type(const xlnt::path &part) const
return override_content_types_.at(part);
}
bool manifest::operator==(const manifest &other) const
{
return default_content_types_ == other.default_content_types_
&& override_content_types_ == other.override_content_types_
&& relationships_ == other.relationships_;
}
} // namespace xlnt

View File

@ -41,7 +41,7 @@ variant::variant(const char *value) : variant(std::string(value))
{
}
variant::variant(int value)
variant::variant(std::int32_t value)
: type_(type::i4),
i4_value_(value)
{
@ -125,6 +125,28 @@ variant::variant(const std::vector<variant> &value)
}
}
bool variant::operator==(const variant &rhs) const
{
if (type_ != rhs.type_)
{
return false;
}
switch (type_)
{
case type::vector:
return vector_value_ == rhs.vector_value_;
case type::i4:
case type::boolean:
return i4_value_ == rhs.i4_value_;
case type::date:
case type::lpstr:
return lpstr_value_ == rhs.lpstr_value_;
case type::null:
return true;
}
return false;
}
bool variant::is(type t) const
{
return type_ == t;

View File

@ -123,4 +123,10 @@ named_range &named_range::operator=(const named_range &other)
return *this;
}
bool named_range::operator==(const named_range &rhs) const
{
return name_ == rhs.name_
&& targets_ == rhs.targets_;
}
} // namespace xlnt

View File

@ -500,6 +500,30 @@ workbook::workbook()
swap(wb_template);
}
workbook::workbook(const xlnt::path &file)
{
*this = empty();
load(file);
}
workbook::workbook(const xlnt::path &file, const std::string &password)
{
*this = empty();
load(file, password);
}
workbook::workbook(std::istream &data)
{
*this = empty();
load(data);
}
workbook::workbook(std::istream &data, const std::string &password)
{
*this = empty();
load(data, password);
}
workbook::workbook(detail::workbook_impl *impl)
: d_(impl)
{
@ -1109,12 +1133,12 @@ void workbook::clear()
bool workbook::operator==(const workbook &rhs) const
{
return d_.get() == rhs.d_.get();
return *d_ == *rhs.d_;
}
bool workbook::operator!=(const workbook &rhs) const
{
return d_.get() != rhs.d_.get();
return !operator==(rhs);
}
void workbook::swap(workbook &right)
@ -1178,9 +1202,7 @@ workbook::workbook(const workbook &other)
d_->stylesheet_.get().parent = this;
}
workbook::~workbook()
{
}
workbook::~workbook() = default;
bool workbook::has_theme() const
{

View File

@ -28,18 +28,18 @@
namespace xlnt {
worksheet_iterator::worksheet_iterator(workbook &wb, std::size_t index)
: wb_(wb), index_(index)
: wb_(&wb), index_(index)
{
}
worksheet_iterator::worksheet_iterator(const worksheet_iterator &rhs)
: wb_(rhs.wb_), index_(rhs.index_)
worksheet_iterator::reference worksheet_iterator::operator*()
{
return (*wb_)[index_];
}
worksheet worksheet_iterator::operator*()
const worksheet_iterator::reference worksheet_iterator::operator*() const
{
return wb_[index_];
return (*wb_)[index_];
}
worksheet_iterator &worksheet_iterator::operator++()
@ -50,11 +50,24 @@ worksheet_iterator &worksheet_iterator::operator++()
worksheet_iterator worksheet_iterator::operator++(int)
{
worksheet_iterator old(wb_, index_);
worksheet_iterator old(*wb_, index_);
++*this;
return old;
}
worksheet_iterator &worksheet_iterator::operator--()
{
--index_;
return *this;
}
worksheet_iterator worksheet_iterator::operator--(int)
{
worksheet_iterator old(*wb_, index_);
--(*this);
return old;
}
bool worksheet_iterator::operator==(const worksheet_iterator &comparand) const
{
return index_ == comparand.index_ && wb_ == comparand.wb_;
@ -65,25 +78,14 @@ bool worksheet_iterator::operator!=(const worksheet_iterator &comparand) const
return !(*this == comparand);
}
worksheet_iterator &worksheet_iterator::operator=(const worksheet_iterator &other)
{
index_ = other.index_;
return *this;
}
const_worksheet_iterator::const_worksheet_iterator(const workbook &wb, std::size_t index)
: wb_(wb), index_(index)
: wb_(&wb), index_(index)
{
}
const_worksheet_iterator::const_worksheet_iterator(const const_worksheet_iterator &rhs)
: wb_(rhs.wb_), index_(rhs.index_)
const const_worksheet_iterator::reference const_worksheet_iterator::operator*() const
{
}
const worksheet const_worksheet_iterator::operator*()
{
return wb_.sheet_by_index(index_);
return wb_->sheet_by_index(index_);
}
const_worksheet_iterator &const_worksheet_iterator::operator++()
@ -94,11 +96,24 @@ const_worksheet_iterator &const_worksheet_iterator::operator++()
const_worksheet_iterator const_worksheet_iterator::operator++(int)
{
const_worksheet_iterator old(wb_, index_);
const_worksheet_iterator old(*wb_, index_);
++*this;
return old;
}
const_worksheet_iterator &const_worksheet_iterator::operator--()
{
--index_;
return *this;
}
const_worksheet_iterator const_worksheet_iterator::operator--(int)
{
const_worksheet_iterator old(*wb_, index_);
--(*this);
return old;
}
bool const_worksheet_iterator::operator==(const const_worksheet_iterator &comparand) const
{
return index_ == comparand.index_ && wb_ == comparand.wb_;

View File

@ -58,16 +58,6 @@ const_cell_iterator::const_cell_iterator(worksheet ws, const cell_reference &cur
}
}
cell_iterator::cell_iterator(const cell_iterator &other)
{
*this = other;
}
const_cell_iterator::const_cell_iterator(const const_cell_iterator &other)
{
*this = other;
}
bool cell_iterator::operator==(const cell_iterator &other) const
{
return ws_ == other.ws_
@ -275,14 +265,18 @@ const_cell_iterator const_cell_iterator::operator++(int)
return old;
}
cell cell_iterator::operator*()
cell_iterator::reference cell_iterator::operator*()
{
return ws_.cell(cursor_);
}
const cell const_cell_iterator::operator*() const
const cell_iterator::reference cell_iterator::operator*() const
{
return ws_.cell(cursor_);
}
const const_cell_iterator::reference const_cell_iterator::operator*() const
{
return ws_.cell(cursor_);
}
} // namespace xlnt

View File

@ -295,4 +295,17 @@ rich_text header_footer::even_footer(location where) const
return even_footers_.at(where);
}
bool header_footer::operator==(const header_footer &rhs) const
{
return align_with_margins_ == rhs.align_with_margins_
&& different_odd_even_ == rhs.different_odd_even_
&& scale_with_doc_ == rhs.scale_with_doc_
&& odd_headers_ == rhs.odd_headers_
&& even_headers_ == rhs.even_headers_
&& first_headers_ == rhs.first_headers_
&& odd_footers_ == rhs.odd_footers_
&& even_footers_ == rhs.even_footers_
&& first_footers_ == rhs.first_footers_;
}
} // namespace xlnt

View File

@ -89,4 +89,13 @@ void page_margins::footer(double footer)
footer_ = footer;
}
bool page_margins::operator==(const page_margins &rhs) const
{
return top_ == rhs.top_
&& left_ == rhs.left_
&& right_ == rhs.right_
&& header_ == rhs.header_
&& footer_ == rhs.footer_;
}
} // namespace xlnt

View File

@ -106,4 +106,15 @@ double page_setup::scale() const
return scale_;
}
bool page_setup::operator==(const page_setup &rhs) const
{
return break_ == rhs.break_
&& sheet_state_ == rhs.sheet_state_
&& paper_size_ == rhs.paper_size_
&& fit_to_page_ == rhs.fit_to_page_
&& fit_to_height_ == rhs.fit_to_height_
&& fit_to_width_ == rhs.fit_to_width_
&& scale_ == rhs.scale_;
}
} // namespace xlnt

View File

@ -140,4 +140,11 @@ phonetic_pr::align phonetic_pr::alignment_from_string(const std::string &str)
return align::no_control;
}
bool phonetic_pr::operator==(const phonetic_pr &rhs) const
{
return font_id_ == rhs.font_id_
&& type_ == rhs.type_
&& alignment_ == rhs.alignment_;
}
} // namespace xlnt

View File

@ -39,9 +39,7 @@ range::range(worksheet ws, const range_reference &reference, major_order order,
{
}
range::~range()
{
}
range::~range() = default;
void range::clear_cells()
{
@ -71,6 +69,11 @@ cell_vector range::operator[](std::size_t index)
return vector(index);
}
const worksheet &range::target_worksheet() const
{
return ws_;
}
range_reference range::reference() const
{
return ref_;

View File

@ -28,7 +28,12 @@
namespace xlnt {
cell_vector range_iterator::operator*() const
range_iterator::reference range_iterator::operator*()
{
return cell_vector(ws_, cursor_, bounds_, order_, skip_null_, false);
}
const range_iterator::reference range_iterator::operator*() const
{
return cell_vector(ws_, cursor_, bounds_, order_, skip_null_, false);
}
@ -47,11 +52,6 @@ range_iterator::range_iterator(worksheet &ws, const cell_reference &cursor,
}
}
range_iterator::range_iterator(const range_iterator &other)
{
*this = other;
}
bool range_iterator::operator==(const range_iterator &other) const
{
return ws_ == other.ws_
@ -168,11 +168,6 @@ const_range_iterator::const_range_iterator(const worksheet &ws, const cell_refer
}
}
const_range_iterator::const_range_iterator(const const_range_iterator &other)
{
*this = other;
}
bool const_range_iterator::operator==(const const_range_iterator &other) const
{
return ws_ == other.ws_
@ -274,7 +269,7 @@ const_range_iterator const_range_iterator::operator++(int)
return old;
}
const cell_vector const_range_iterator::operator*() const
const const_range_iterator::reference const_range_iterator::operator*() const
{
return cell_vector(ws_, cursor_, bounds_, order_, skip_null_, false);
}

View File

@ -136,6 +136,7 @@ private:
xlnt_assert(cell.data_type() == xlnt::cell::type::empty);
xlnt_assert(cell.column() == "A");
xlnt_assert(cell.column_index() == 1);
xlnt_assert(cell.row() == 1);
xlnt_assert(cell.reference() == "A1");
xlnt_assert(!cell.has_value());

View File

@ -24,6 +24,8 @@
#include <algorithm>
#include <iostream>
#include <xlnt/xlnt.hpp>
#include <detail/serialization/open_stream.hpp>
#include <helpers/temporary_file.hpp>
#include <helpers/test_suite.hpp>
@ -50,6 +52,7 @@ public:
register_test(test_index_operator);
register_test(test_contains);
register_test(test_iter);
register_test(test_const_iter);
register_test(test_get_index);
register_test(test_get_sheet_names);
register_test(test_add_named_range);
@ -62,6 +65,7 @@ public:
register_test(test_clear);
register_test(test_comparison);
register_test(test_id_gen);
register_test(test_load_file);
}
void test_active_sheet()
@ -110,12 +114,12 @@ public:
xlnt_assert_equals(wb.sheet_titles().at(1), "Active");
xlnt_assert_equals(wb.sheet_by_index(1).cell("B3").value<int>(), 2);
}
void test_remove_sheet()
{
xlnt::workbook wb, wb2;
auto new_sheet = wb.create_sheet(0);
new_sheet.title("removed");
new_sheet.title("removed");
wb.remove_sheet(new_sheet);
xlnt_assert(!wb.contains("removed"));
xlnt_assert_throws(wb.remove_sheet(wb2.active_sheet()), std::runtime_error);
@ -133,14 +137,14 @@ public:
const auto &wb_const = wb;
xlnt_assert_throws(wb_const.sheet_by_title("error"), xlnt::key_not_found);
}
void test_get_sheet_by_title_const()
{
xlnt::workbook wb;
auto new_sheet = wb.create_sheet();
std::string title = "my sheet";
new_sheet.title(title);
const xlnt::workbook& wbconst = wb;
const xlnt::workbook &wbconst = wb;
auto found_sheet = wbconst.sheet_by_title(title);
xlnt_assert_equals(new_sheet, found_sheet);
}
@ -158,17 +162,100 @@ public:
xlnt_assert(wb.contains("Sheet1"));
xlnt_assert(!wb.contains("NotThere"));
}
void test_iter()
{
xlnt::workbook wb;
for(auto ws : wb)
for (auto ws : wb)
{
xlnt_assert_equals(ws.title(), "Sheet1");
}
xlnt::workbook wb2;
auto iter = wb.begin();
auto iter_copy(iter); // copy ctor
xlnt_assert_equals(iter, iter_copy);
auto begin_2(wb2.begin());
xlnt_assert_differs(begin_2, iter);
iter = begin_2; // copy assign
xlnt_assert_equals(iter, begin_2);
iter = wb.begin();
iter = std::move(begin_2);
xlnt_assert_equals(iter, wb2.begin());
auto citer = wb.cbegin();
auto citer_copy(citer); // copy ctor
xlnt_assert_equals(citer, citer_copy);
auto cbegin_2(wb2.cbegin());
xlnt_assert_differs(cbegin_2, citer);
citer = cbegin_2; // copy assign
xlnt_assert_equals(citer, cbegin_2);
citer = wb.cbegin();
citer = std::move(cbegin_2);
xlnt_assert_equals(citer, wb2.cbegin());
wb2.create_sheet(); // wb2 iterators assumed invalidated
iter = wb2.begin();
xlnt_assert_equals((*iter).title(), "Sheet1");
++iter;
xlnt_assert_differs(iter, wb2.begin());
xlnt_assert_equals((*iter).title(), "Sheet2");
auto temp = --iter;
xlnt_assert_equals((*temp).title(), "Sheet1");
xlnt_assert_equals((*iter).title(), "Sheet1");
iter++;
xlnt_assert_equals((*iter).title(), "Sheet2");
temp = iter++;
xlnt_assert_equals((*temp).title(), "Sheet2");
xlnt_assert_equals(iter, wb2.end());
iter = temp--;
xlnt_assert_equals((*iter).title(), "Sheet2");
xlnt_assert_equals((*temp).title(), "Sheet1");
}
void test_const_iter()
{
const xlnt::workbook wb;
for (auto ws : wb)
{
xlnt_assert_equals(ws.title(), "Sheet1");
}
xlnt::workbook wb2;
auto iter = wb.cbegin();
auto iter_copy(iter); // copy ctor
xlnt_assert_equals(iter, iter_copy);
auto begin_2(wb2.cbegin());
xlnt_assert_differs(begin_2, iter);
iter = begin_2; // copy assign
xlnt_assert_equals(iter, begin_2);
iter = wb.cbegin();
iter = std::move(begin_2);
xlnt_assert_equals(iter, wb2.cbegin());
// wb2 iterators assumed invalidated
wb2.create_sheet();
iter = wb2.cbegin();
xlnt_assert_equals((*iter).title(), "Sheet1");
++iter;
xlnt_assert_differs(iter, wb2.cbegin());
xlnt_assert_equals((*iter).title(), "Sheet2");
auto temp = --iter;
xlnt_assert_equals((*temp).title(), "Sheet1");
xlnt_assert_equals((*iter).title(), "Sheet1");
iter++;
xlnt_assert_equals((*iter).title(), "Sheet2");
temp = iter++;
xlnt_assert_equals((*temp).title(), "Sheet2");
xlnt_assert_equals(iter, wb2.cend());
iter = temp--;
xlnt_assert_equals((*iter).title(), "Sheet2");
xlnt_assert_equals((*temp).title(), "Sheet1");
}
void test_get_index()
{
xlnt::workbook wb;
@ -187,11 +274,11 @@ public:
xlnt::workbook wb;
wb.create_sheet().title("test_get_sheet_titles");
const std::vector<std::string> expected_titles = { "Sheet1", "test_get_sheet_titles" };
const std::vector<std::string> expected_titles = {"Sheet1", "test_get_sheet_titles"};
xlnt_assert_equals(wb.sheet_titles(), expected_titles);
xlnt_assert_equals(wb.sheet_titles(), expected_titles);
}
void test_add_named_range()
{
xlnt::workbook wb, wb2;
@ -201,7 +288,7 @@ public:
xlnt_assert(wb.has_named_range("test_nr"));
xlnt_assert_throws(wb2.create_named_range("test_nr", new_sheet, "A1"), std::runtime_error);
}
void test_get_named_range()
{
xlnt::workbook wb;
@ -256,7 +343,7 @@ public:
wb.create_sheet().title("Sheet3");
auto iter = wb.begin();
xlnt_assert_equals((*iter).title(), "Sheet1");
xlnt_assert_equals((*iter).title(), "Sheet1");
iter++;
xlnt_assert_equals((*iter).title(), "Sheet2");
@ -274,10 +361,10 @@ public:
xlnt_assert_equals((*iter).title(), "Sheet3");
xlnt_assert_equals(iter, copy);
}
void test_manifest()
{
xlnt::manifest m;
xlnt::manifest m;
xlnt_assert(!m.has_default_type("xml"));
xlnt_assert_throws(m.default_type("xml"), xlnt::key_not_found);
xlnt_assert(!m.has_relationship(xlnt::path("/"), xlnt::relationship_type::office_document));
@ -304,7 +391,7 @@ public:
xlnt_assert(wb.active_sheet().cell("B2").has_style());
wb.clear_styles();
xlnt_assert(!wb.active_sheet().cell("B2").has_style());
xlnt::format format = wb.create_format();
xlnt::format format = wb.create_format();
xlnt::font font;
font.size(41);
format.font(font, true);
@ -323,13 +410,13 @@ public:
xlnt_assert(!(wb != wb));
xlnt_assert(!(wb == wb2));
xlnt_assert(wb != wb2);
const auto &wb_const = wb;
//TODO these aren't tests...
wb_const.manifest();
xlnt_assert(wb.has_theme());
wb.create_style("style1");
wb.style("style1");
wb_const.style("style1");
@ -344,5 +431,40 @@ public:
wb.create_sheet();
xlnt_assert_differs(wb[1].id(), wb[2].id());
}
void test_load_file()
{
xlnt::path file = path_helper::test_file("2_minimal.xlsx");
xlnt::workbook wb_path(file);
// ctor from ifstream
std::ifstream file_reader(file.string(), std::ios::binary);
xlnt_assert_equals(wb_path, xlnt::workbook(file_reader));
// load with string
xlnt::workbook wb_load1;
xlnt_assert_differs(wb_path, wb_load1);
wb_load1.load(file.string());
xlnt_assert_equals(wb_path, wb_load1);
// load with wstring
xlnt::workbook wb_load2;
wb_load2.load(file.string());
xlnt_assert_equals(wb_path, wb_load2);
// load with path
xlnt::workbook wb_load3;
wb_load3.load(file);
xlnt_assert_equals(wb_path, wb_load3);
// load with istream
xlnt::workbook wb_load4;
std::ifstream file_reader2(file.string(), std::ios::binary);
wb_load4.load(file_reader2);
xlnt_assert_equals(wb_path, wb_load4);
// load with vector
std::ifstream file_reader3(file.string(), std::ios::binary);
file_reader3.unsetf(std::ios::skipws);
std::vector<uint8_t> data(std::istream_iterator<uint8_t>{file_reader3},
std::istream_iterator<uint8_t>());
xlnt::workbook wb_load5;
wb_load5.load(data);
xlnt_assert_equals(wb_path, wb_load5);
}
};
static workbook_test_suite x;