xtd 0.2.0
Loading...
Searching...
No Matches

◆ ienumerator

Supports a simple iteration over a non-generic collection.

Supports a simple iteration over a generic collection.
Definition ienumerator.h:58
Header
#include <xtd/collections/ienumerator>
Namespace
xtd::collections
Library
xtd.core

The following code example demonstrates the best practice for iterating a custom collection by implementing the xtd::collection::ienumerable and xtd::collection::ienumerator interfaces. In this example, members of these interfaces are not explicitly called, but they are implemented to support the use of for each to iterate through the collection. This example is a complete Console app.

#include <xtd/collections/array_list>
#include <xtd/console>
#include <xtd/startup>
using namespace xtd;
using namespace xtd::collections;
class program {
public:
// Simple business object.
struct person : public object, public iequatable<person>, public icomparable<person> {
public:
person(const string& first_name, const string last_name) : first_name {first_name}, last_name {last_name} {}
string first_name;
string last_name;
int32 compare_to(const person& o) const noexcept override {
if (first_name == o.first_name && last_name == o.last_name) return 0;
if (first_name > o.first_name || (first_name == o.first_name && last_name > o.last_name)) return 1;
return -1;
}
bool equals(const object& o) const noexcept override {return is<person>(o) && equals(as<person>(o));}
bool equals(const person& o) const noexcept override {return compare_to(o) == 0;}
string to_string() const noexcept override {return string::format("{} {}", first_name, last_name);}
};
// Collection of person objects. This class implements xtd::collections::ienumerable so that it can be used with for each syntax.
class people : public ienumerable {
private:
array_list people_;
public:
people(const array<person>& p_array) {
people_ = array_list(p_array.size());
for (auto i = 0_z; i < p_array.size(); ++i)
people_[i] = p_array[i];
}
// Implementation for the xtd::collections::ienumerable::get_enumerator method.
enumerator get_enumerator() const override {
return enumerator {new_ptr<people_enumerator>(people_)};
}
};
// When you implement xtd::collections::ienumerable, you must also implement xtd::collections::ienumerator.
class people_enumerator : public ienumerator {
private:
const array_list& people_;
// Enumerators are positioned before the first element until the first xtd::collections::ienumerator::move_next() call.
size position = array_list::npos;
public:
people_enumerator(const array_list& list) : people_(list) {}
bool move_next() override {return ++position < people_.count();}
void reset() override {position = array_list::npos;}
const any_object& current() const override {
if (position >= people_.size()) throw invalid_operation_exception {csf_};
return people_[position];
}
};
static auto main() -> void {
auto people_array = xtd::array<person> {
person {"John", "Smith"},
person {"Jim", "Johnson"},
person {"Sue", "Rabon"},
};
auto people_list = people {people_array};
for (auto person : people_list)
console::write_line(person);
}
};
startup_(program::main);
// This code produces the following output :
//
// John Smith
// Jim Johnson
// Sue Rabon
Represent a polymorphic wrapper capable of holding any type.
Definition any_object.h:28
Supports a simple iteration over a generic collection.
Definition enumerator.h:31
Exposes the enumerator, which supports a simple iteration over a collection of a specified type.
Definition ienumerable.h:35
size_type count() const noexcept override
Gets the number of elements contained in the xtd::collections::generic::list <type_t>.
Definition list.h:288
virtual size_type size() const noexcept
Returns the number of elements in the container, i.e. std::distance(xtd::collections::generic::list::...
Definition list.h:364
Represents a strongly typed list of objects that can be accessed by index. Provides methods to search...
Definition list.h:71
Represents the standard input, output, and error streams for console applications.
Definition console.h:36
Defines a generalized comparison method that a value type or class implements to create a type-specif...
Definition icomparable.h:21
Defines a generalized method that a value type or class implements to create a type-specific method f...
Definition iequatable.h:22
The exception that is thrown when a method call is invalid for the object's current state.
Definition invalid_operation_exception.h:18
Supports all classes in the xtd class hierarchy and provides low-level services to derived classes....
Definition object.h:42
#define startup_(main_method)
Defines the entry point to be called when the application loads. Generally this is set either to the ...
Definition startup.h:175
#define csf_
Provides information about the current stack frame.
Definition current_stack_frame.h:30
int32_t int32
Represents a 32-bit signed integer.
Definition int32.h:23
size_t size
Represents a size of any object in bytes.
Definition size.h:23
std::string to_string(const value_t &value, const std::string &fmt, const std::locale &loc)
Convert a specified value into a string with specified format and locale.
Definition to_string.h:41
@ i
The I key.
@ o
The O key.
The xtd::collections namespace contains interfaces and classes that define various collections of obj...
Definition any_pair.h:12
std::vector< type_t > array
Definition __array_definition.h:18
The xtd namespace contains all fundamental classes to access Hardware, Os, System,...
Definition xtd_about_box.h:10
Remarks
xtd::collections::ienumerator is the base interface for all non-generic enumerators. Its generic equivalent is the xtd::collections::generic::iznumerator <type_t> interface.
The for each statement of the C++ language hides the complexity of the enumerators. Therefore, using for each is recommended instead of directly manipulating the enumerator.
Enumerators can be used to read the data in the collection, but they cannot be used to modify the underlying collection.
The xtd::collections::ienumerator::reset method is provided for COM interoperability and does not need to be fully implemented; instead, the implementer can throw a xtd::not_supported_exception.
Initially, the enumerator is positioned before the first element in the collection. You must call the xtd::collections::ienumerator::MMoveN_next method to advance the enumerator to the first element of the collection before reading the value of xtd::collections::ienumerator::current; otherwise, xtd::collections::ienumerator::current is undefined.
xtd::collections::ienumerator::current returns the same object until either xtd::collections::ienumerator::move_next or xtd::collections::ienumerator::reset is called. xtd::collections::ienumerator::move_next sets xtd::collections::ienumerator::current to the next element.
If xtd::collections::ienumerator::move_next passes the end of the collection, the enumerator is positioned after the last element in the collection and xtd::collections::ienumerator::move_next returns false. When the enumerator is at this position, subsequent calls to xtd::collections::ienumerator::move_next also return false. If the last call to xtd::collections::ienumerator::move_next returned false, xtd::collections::ienumerator::current is undefined.
To set xtd::collections::ienumerator::current to the first element of the collection again, you can call Reset, if it's implemented, followed by xtd::collections::ienumerator::move_next. If xtd::collections::ienumerator::reset is not implemented, you must create a new enumerator instance to return to the first element of the collection.
If changes are made to the collection, such as adding, modifying, or deleting elements, the behavior of the enumerator is undefined.
The enumerator does not have exclusive access to the collection; therefore, enumerating through a collection is intrinsically not a thread-safe procedure. Even when a collection is synchronized, other threads can still modify the collection, which causes the enumerator to throw an exception. To guarantee thread safety during enumeration, you can either lock the collection during the entire enumeration or catch the exceptions resulting from changes made by other threads.