add iterable
parent
765bfc3502
commit
2935b29e2e
@ -1,2 +1,5 @@
|
|||||||
*.o
|
*.o
|
||||||
.*.swp
|
.*.swp
|
||||||
|
raw_ptr
|
||||||
|
smart_ptr
|
||||||
|
smart_ptr_iterable
|
||||||
|
|||||||
@ -1,8 +1,9 @@
|
|||||||
run: wrappers
|
run: all
|
||||||
./wrappers
|
./raw_ptr
|
||||||
|
./smart_ptr
|
||||||
|
./iterable
|
||||||
|
|
||||||
wrappers: main.c
|
all: raw_ptr smart_ptr iterable
|
||||||
g++ -Wall -o wrappers main.c
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f *.o wrappers
|
rm -f *.o raw_ptr smart_ptr iterable
|
||||||
|
|||||||
@ -0,0 +1,24 @@
|
|||||||
|
Wrappers and iterators examples
|
||||||
|
===============================
|
||||||
|
|
||||||
|
Build and run:
|
||||||
|
|
||||||
|
```
|
||||||
|
make
|
||||||
|
```
|
||||||
|
|
||||||
|
`raw_ptr.cc`
|
||||||
|
------------
|
||||||
|
|
||||||
|
Simply raw pointer wrapper. Shows how we can do an object abilities extension in the runtime. Useful for iterators.
|
||||||
|
|
||||||
|
`smart_ptr.cc`
|
||||||
|
--------------
|
||||||
|
|
||||||
|
Similar example, but holds the shared pointer.
|
||||||
|
|
||||||
|
`iterable.cc`
|
||||||
|
-------------
|
||||||
|
|
||||||
|
Finally, the iterable with traversing algorithm compile-time instantiated. The template method returns an iterable object, which iterates over IShape's with its `.get_next()`/`.get_prev()`.
|
||||||
|
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include "main.h"
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
auto c1 = std::make_shared<Circle>(3.0);
|
||||||
|
auto c2 = std::make_shared<Circle>(5.0);
|
||||||
|
auto c3 = std::make_shared<Circle>(7.0);
|
||||||
|
|
||||||
|
c1->set_next(c2.get());
|
||||||
|
c2->set_next(c3.get());
|
||||||
|
|
||||||
|
std::cout << "Forward:\n";
|
||||||
|
for (auto& shape : c1->traverse<IShape::forward>()) {
|
||||||
|
shape.draw();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "\nBackward:\n";
|
||||||
|
for (auto& shape : c1->traverse<IShape::backward>()) {
|
||||||
|
shape.draw();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,68 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class Iterator {
|
||||||
|
protected:
|
||||||
|
T* current;
|
||||||
|
public:
|
||||||
|
explicit Iterator(T* ptr) : current(ptr) {}
|
||||||
|
|
||||||
|
T& operator*() const { return *current; }
|
||||||
|
T* operator->() const { return current; }
|
||||||
|
|
||||||
|
bool operator!=(const Iterator& other) const {
|
||||||
|
return current != other.current;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual Iterator& operator++() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T, typename Policy>
|
||||||
|
class Traversal {
|
||||||
|
T* start;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit Traversal(T* start) : start(start) {}
|
||||||
|
|
||||||
|
Policy begin() const { return Policy(start); }
|
||||||
|
Policy end() const { return Policy(nullptr); }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct IteratorForward : public Iterator<T> {
|
||||||
|
explicit IteratorForward(T* ptr) : Iterator<T>(first(ptr)) {}
|
||||||
|
|
||||||
|
static T* first(T* node) {
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
static T* next(T* node) {
|
||||||
|
return node ? node->get_next() : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
Iterator<T>& operator++() override {
|
||||||
|
this->current = next(this->current);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct IteratorBackward : public Iterator<T> {
|
||||||
|
explicit IteratorBackward(T* ptr) : Iterator<T>(first(ptr)) {}
|
||||||
|
|
||||||
|
static T* first(T* node) {
|
||||||
|
if (!node) return nullptr;
|
||||||
|
while (node->get_next()) node = node->get_next();
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
static T* next(T* node) {
|
||||||
|
return node ? node->get_prev() : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
Iterator<T>& operator++() override {
|
||||||
|
this->current = next(this->current);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
@ -0,0 +1,43 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "iterators.h"
|
||||||
|
|
||||||
|
class IShape {
|
||||||
|
IShape* next = nullptr;
|
||||||
|
IShape* prev = nullptr;
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual ~IShape() = default;
|
||||||
|
virtual void draw() const = 0;
|
||||||
|
virtual double area() const = 0;
|
||||||
|
|
||||||
|
void set_next(IShape* n) {
|
||||||
|
next = n;
|
||||||
|
if (n) n->prev = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
IShape* get_next() const { return next; }
|
||||||
|
IShape* get_prev() const { return prev; }
|
||||||
|
|
||||||
|
template<typename Policy>
|
||||||
|
Traversal<IShape, Policy> traverse() {
|
||||||
|
return Traversal<IShape, Policy>(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
using forward = IteratorForward<IShape>;
|
||||||
|
using backward = IteratorBackward<IShape>;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Circle : public IShape {
|
||||||
|
double r;
|
||||||
|
public:
|
||||||
|
Circle(double radius) : r(radius) {}
|
||||||
|
|
||||||
|
void draw() const override {
|
||||||
|
std::cout << "Drawing Circle of radius " << r << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
double area() const override {
|
||||||
|
return 3.14159 * r * r;
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -0,0 +1,44 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <memory>
|
||||||
|
#include "main.h"
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
class Wrapper {
|
||||||
|
std::shared_ptr<T> impl;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit Wrapper(std::shared_ptr<T> ptr) : impl(std::move(ptr)) {}
|
||||||
|
|
||||||
|
T* operator->() { return impl.get(); }
|
||||||
|
const T* operator->() const { return impl.get(); }
|
||||||
|
|
||||||
|
std::shared_ptr<T> get() const { return impl; }
|
||||||
|
|
||||||
|
operator std::shared_ptr<T>() const { return impl; }
|
||||||
|
operator const std::shared_ptr<T>&() const { return impl; }
|
||||||
|
operator std::shared_ptr<T>&() { return impl; }
|
||||||
|
|
||||||
|
void myHelper() const {
|
||||||
|
std::cout << "[Wrapper] Helper method called\n";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void draw_shape(const std::shared_ptr<IShape>& shape) {
|
||||||
|
shape->draw();
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
auto circle = std::make_shared<Circle>(10.0);
|
||||||
|
Wrapper<IShape> wrapped(circle);
|
||||||
|
|
||||||
|
wrapped->draw();
|
||||||
|
|
||||||
|
std::cout << "Area: " << wrapped->area() << "\n";
|
||||||
|
|
||||||
|
wrapped.myHelper();
|
||||||
|
|
||||||
|
draw_shape(wrapped);
|
||||||
|
|
||||||
|
std::shared_ptr<IShape> copy = wrapped;
|
||||||
|
draw_shape(copy);
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue