Shows how to use xtd::collections::generic::ilist interface.
#include <xtd/xtd>
class program {
public:
static auto main() -> void {
auto boxes = box_collection {};
boxes.add(program::box {10, 4, 6});
boxes.add(program::box {4, 6, 10});
boxes.add(program::box {6, 10, 4});
boxes.add(program::box {12, 8, 10});
boxes.add(program::box {10, 4, 6});
display(boxes);
console::write_line("Removing 6x10x4");
boxes.remove(program::box {6, 10, 4});
display(boxes);
auto box_check = program::box {8, 12, 10};
console::write_line("Contains {}x{}x{} by dimensions: {}", box_check.height, box_check.length, box_check.width, boxes.contains(box_check));
console::write_line("Contains {}x{}x{} by volume: {}", box_check.height, box_check.length, box_check.width, boxes.contains(box_check, box_same_volume {}));
}
struct box : public object, public iequatable<program::box> {
box() = default;
box(int h, int l, int w) : height {h}, length{l}, width {w} {}
int height = 0;
int length = 0;
int width = 0;
bool equals(const object& o) const noexcept override {return is<program::box>(o) && equals(as<program::box>(o));}
bool equals(const program::box& o) const noexcept override {return box_same_dimensions {}.equals(*this, o);}
};
class box_collection : public ilist<program::box> {
public:
box_collection(const std::initializer_list<program::box>& boxes) : boxes_(boxes) {}
size count() const noexcept override {return boxes_.count();}
bool is_fixed_size() const noexcept override {return false;}
bool is_read_only() const noexcept override {return false;}
bool is_synchronized() const noexcept override {return false;}
const object& sync_root() const noexcept override {return sync_root_;}
void add(const program::box& item) override {
if (!contains(item))
boxes_.add(item);
else
console::write_line("A box with {}x{}x{} dimensions was already added to the collection.", item.height, item.length, item.width);
}
void clear() override {boxes_.clear();}
bool contains(const program::box& item) const noexcept override {return index_of(item) != npos;}
bool contains(const program::box& item, const iequality_comparer<program::box>& comparer) const noexcept {
for (auto box : boxes_)
if (comparer.
equals(box, item))
return true;
return false;
}
void copy_to(array<program::box>& array, size array_index) const override {boxes_.copy_to(array, array_index);}
enumerator<program::box> get_enumerator() const override {return {new_ptr<box_enumerator>(boxes_)};}
size index_of(const program::box& item) const noexcept override {
for (auto index = 0_z; index < count(); ++index)
if (boxes_[index] == item) return index;
return npos;
}
void insert(size index, const program::box& item) override {
if (index >= count()) throw argument_out_of_range_exception {};
boxes_.insert(boxes_.begin() + index, item);
}
bool remove(const program::box& item) override {return boxes_.remove(item);}
void remove_at(size index) override {
if (index >= count()) throw argument_out_of_range_exception {};
boxes_.erase(boxes_.begin() + index);
}
const program::box& operator [](size index) const override {
if (index >= count()) throw argument_out_of_range_exception {};
return boxes_[index];
}
program::box& operator [](size index) override {
if (index >= count()) throw argument_out_of_range_exception {};
return boxes_[index];
}
private:
list<program::box> boxes_;
object sync_root_;
};
class box_enumerator : public ienumerator<program::box> {
public:
explicit box_enumerator(const list<program::box>& items) : items_(items) {}
const program::box& current() const override {return items_[index_];}
bool move_next() override {return ++index_ < items_.size();}
void reset() override {index_ = box_integer<size>::max_value;}
protected:
const list<program::box>& items_;
size index_ = box_integer<size>::max_value;
};
class box_same_dimensions : public iequality_comparer<program::box> {
public:
bool equals(const program::box& b1, const program::box& b2) const noexcept override {return b1.height == b2.height && b1.length == b2.length && b1.width == b2.width;}
size get_hash_code(const program::box& box) const noexcept override {return hash_code::combine(box.height, box.length, box.width);}
};
class box_same_volume : public iequality_comparer<program::box> {
public:
bool equals(const program::box& b1, const program::box& b2) const noexcept override {return b1.height * b1.length * b1.width == b2.height * b2.length * b2.width;}
size get_hash_code(const program::box& box) const noexcept override {
auto hash_code = hash_code::combine(box.height, box.length, box.width);
console::write_line("HC: {}", hash_code);
return hash_code;
}
};
static void display(const box_collection& boxes) {
console::write_line("\nheight length width hash code");
for (auto index = 0_z; index < boxes.count(); ++index)
console::write_line("{,-6} {,-6} {,-6} {}", boxes[index].height, boxes[index].length, boxes[index].width, boxes[index].get_hash_code());
console::write_line();
}
};
virtual bool equals(const object &obj) const noexcept
Determines whether the specified object is equal to the current object.
#define startup_(main_method)
Defines the entry point to be called when the application loads. Generally this is set either to the ...
Definition startup.hpp:168