Supporting standard library movement algorithms in a custom type
How do you implement a custom container that supports all the std::ranges
movement algorithms?
Implementing a custom container that supports all the std::ranges
movement algorithms requires adhering to the iterator requirements expected by these algorithms.
Here's a step-by-step guide on how to create a simple custom container:
Define the Container
Start by defining a basic container that holds elements and provides access to them:
#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>
template<typename T>
class MyContainer {
std::vector<T> data;
public:
void add(const T& value) {
data.push_back(value);
}
};
Ensure Iterator Support
To support std::ranges
algorithms, your container must provide iterators. This involves implementing begin()
, end()
, and their const counterparts:
#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>
template<typename T>
class MyContainer {
std::vector<T> data;
public:
void add(const T& value) {
data.push_back(value);
}
// Iterator types
using iterator =
typename std::vector<T>::iterator;
using const_iterator =
typename std::vector<T>::const_iterator;
// Methods to return iterators
iterator begin() {
return data.begin();
}
const_iterator begin() const {
return data.begin();
}
iterator end() {
return data.end();
}
const_iterator end() const {
return data.end();
}
};
Implementing Movement Algorithms
With iterators in place, you can now use std::ranges
algorithms with your custom container:
#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>
class MyContainer {/*...*/};
int main() {
MyContainer<int> container;
container.add(1);
container.add(2);
container.add(3);
// Using std::ranges::move
MyContainer<int> destination;
destination.add(0);
destination.add(0);
destination.add(0);
std::ranges::move(
container.begin(),
container.end(),
destination.begin()
);
for (const auto& value : destination) {
std::cout << value << " ";
}
}
1 2 3
Full Example with std::ranges::reverse()
Here's a complete example using std::ranges::reverse()
with our custom container:
#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>
class MyContainer {/*...*/};
int main() {
MyContainer<int> container;
container.add(1);
container.add(2);
container.add(3);
// Using std::ranges::reverse
std::ranges::reverse(container);
for (const auto& value : container) {
std::cout << value << " ";
}
}
3 2 1
Conclusion
By ensuring your custom container supports iterators, you can use all std::ranges
movement algorithms effectively.
Implementing begin()
and end()
methods is crucial for this support, enabling you to leverage powerful standard algorithms with your custom data structures.
Movement Algorithms
An introduction to the seven movement algorithms in the C++ standard library: move()
, move_backward()
, rotate()
, reverse()
, shuffle()
, shift_left()
, and shift_right()
.