test.cpp


1
#include <tuple>
2
#include <utility>
3
#include <iostream>
4
#include <cstddef>
5
6
enum class color { red, blue, black };
7
8
class Geo {
9
  public:
10
    virtual void draw () const = 0;
11
};
12
13
class Circle : public Geo {
14
  public:
15
    struct Data {
16
      int x, y, r;
17
      color fgcolor, bgcolor;
18
    } data;
19
    constexpr Circle (const Data& data) : data(data) {}
20
    
21
    virtual void draw () const override;
22
};
23
24
class Rectangle : public Geo {
25
  public:
26
    struct Data {
27
      int x, y, w, h;
28
      color fgcolor;
29
    } data;
30
    constexpr Rectangle (const Data& data) : data(data) {}
31
32
    virtual void draw () const override;
33
};
34
35
class Textfield : public Geo {
36
  public:
37
    struct Data {
38
      int x, y, w, h;
39
      color fgcolor;
40
      const char* s;
41
    } data;
42
    constexpr Textfield (const Data& data) : data(data) {}
43
44
    virtual void draw () const override;
45
};
46
47
void Circle::draw () const {
48
  std::cout << "Circle::draw\n";
49
}
50
51
void Rectangle::draw () const {
52
  std::cout << "Rectangle::draw\n";
53
}
54
55
void Textfield::draw () const {
56
  std::cout << "Textfield::draw\n";
57
}
58
59
60
template <typename Base, typename... T, std::size_t... I>
61
constexpr std::array<Base*, sizeof...(T)> tuple_pointers (std::tuple<T...>& t, std::index_sequence<I...>) {
62
  return {{ &std::get<I> (t) ... }};
63
}
64
65
template <typename... T>
66
class PolymorphicContainer {
67
  public:
68
    constexpr PolymorphicContainer (T&&... objs)
69
      :  tuple (std::forward<T> (objs)...),
70
        array { tuple_pointers<Geo> (tuple, std::index_sequence_for<T...> {}) } {}
71
    
72
    std::tuple<T...> tuple;
73
    std::array<Geo*, sizeof...(T)> array;
74
};
75
76
constexpr PolymorphicContainer MainScreen {
77
  Circle({.x=0, .y=10, .r=20, .fgcolor=color::red, .bgcolor=color::red }),
78
  Rectangle({.x=100, .y=10, .w=20, .h=10, .fgcolor=color::blue }),
79
  Textfield({.x=100, .y=10, .w=20, .h=10, .fgcolor=color::black, .s="Hallo" }),
80
};
81
82
template <typename F, typename... T, std::size_t... I>
83
void staticIteration (const std::tuple<T...>& t, F&& f, std::index_sequence<I...>) {
84
  ((f (std::get<I> (t)), 0), ...);
85
}
86
87
template <typename F, typename... T>
88
void staticIteration (const std::tuple<T...>& t, F&& f) {
89
  staticIteration (t, std::forward<F> (f), std::index_sequence_for<T...> {});
90
}
91
92
int main () {
93
  for (const Geo* obj : MainScreen.array) {
94
    obj->draw ();
95
  }
96
  
97
  staticIteration (MainScreen.tuple, [&] (const auto& elem) {
98
    elem.draw ();
99
  });
100
}