6.1 预想方案

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include <iostream>
#include <vector>
#include <memory>

struct Point
{
int x, y;
};

struct Line
{
Point start, end;
};

struct VectorObject
{
virtual std::vector<Line>::iterator begin() = 0;
virtual std::vector<Line>::iterator end() = 0;
};

struct VectorRectangle : VectorObject
{
VectorRectangle(int x, int y, int width, int height)
{
lines.emplace_back(Line{ Point{x, y}, Point{x + width, y} });
lines.emplace_back(Line{ Point{x + width, y}, Point{x + width, y + height} });
lines.emplace_back(Line{ Point{x, y}, Point{x, y + height} });
lines.emplace_back(Line{ Point{x, y + height}, Point{x + width, y + height} });
}

std::vector<Line>::iterator begin() override
{
return lines.begin();
}

std::vector<Line>::iterator end() override
{
return lines.end();
}

private:
std::vector<Line> lines;
};

void DrawPoints(/*std::CPaintDC& dc, */std::vector<Point>::iterator start,
std::vector<Point>::iterator end)
{
for (auto i = start; i != end; ++i)
std::cout << i->x << " " << i->y << std::endl;
}
int main(void)
{
std::vector<std::shared_ptr<VectorObject>> vectorObjects{
std::make_shared<VectorRectangle>(10, 10, 100, 100),
std::make_shared<VectorRectangle>(30, 30, 60, 60)
};

return 0;
}

6.2 适配器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#include <iostream>
#include <vector>
#include <algorithm>
#include <memory>

struct Point
{
int x, y;
};

struct Line
{
Point start, end;
};

struct VectorObject
{
virtual std::vector<Line>::iterator begin() = 0;
virtual std::vector<Line>::iterator end() = 0;
};

struct VectorRectangle : VectorObject
{
VectorRectangle(int x, int y, int width, int height)
{
lines.emplace_back(Line{ Point{x, y}, Point{x + width, y} });
lines.emplace_back(Line{ Point{x + width, y}, Point{x + width, y + height} });
lines.emplace_back(Line{ Point{x, y}, Point{x, y + height} });
lines.emplace_back(Line{ Point{x, y + height}, Point{x + width, y + height} });
}

std::vector<Line>::iterator begin() override
{
return lines.begin();
}

std::vector<Line>::iterator end() override
{
return lines.end();
}

private:
std::vector<Line> lines;
};

void DrawPoints(/*std::CPaintDC& dc, */std::vector<Point>::iterator start,
std::vector<Point>::iterator end)
{
for (auto i = start; i != end; ++i)
std::cout << i->x << " " << i->y << std::endl;
}

struct LineToPointAdapter
{
typedef std::vector<Point> Points;

LineToPointAdapter(const Line& line)
{
int left = std::min(line.start.x, line.end.x);
int right = std::max(line.start.x, line.end.x);
int top = std::min(line.start.y, line.end.y);
int bottom = std::max(line.start.y, line.end.y);
int dx = right - left;
int dy = line.end.y - line.start.y;

if (dx == 0)
{
for (int y = top; y <= bottom; ++y)
{
points.emplace_back(Point{left, y});
}
}
else if (dy == 0)
{
for (int x = left; x <= right; ++x)
{
points.emplace_back(Point{x, top});
}
}
}

virtual Points::iterator begin() { return points.begin(); };
virtual Points::iterator end() { return points.end(); };
private:
Points points;
};

int main(void)
{
std::vector<std::shared_ptr<VectorObject>> vectorObjects{
std::make_shared<VectorRectangle>(10, 10, 100, 100),
std::make_shared<VectorRectangle>(30, 30, 60, 60)
};

for (const auto& obj: vectorObjects)
{
for (const auto& line: *obj)
{
LineToPointAdapter lpo{ line };
DrawPoints(lpo.begin(), lpo.end());
}
}

return 0;
}

6.3 临时适配器对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#include <iostream>
#include <vector>
#include <algorithm>
#include <memory>
//#include <boost/container_hash/hash_fwd.hpp>
#include <boost/container_hash/hash.hpp>
#include <map>
#include <functional>

struct Point
{
int x, y;

friend size_t hash_value(const Point& obj)
{
size_t seed = 0x725C686F;
boost::hash_combine(seed, obj.x);
boost::hash_combine(seed, obj.y);
return seed;
}
};

struct Line
{
Point start, end;

friend size_t hash_value(const Line& obj)
{
size_t seed = 0x719E6B16;
boost::hash_combine(seed, obj.start);
boost::hash_combine(seed, obj.end);
return seed;
}
};

struct VectorObject
{
virtual std::vector<Line>::iterator begin() = 0;
virtual std::vector<Line>::iterator end() = 0;
};

struct VectorRectangle : VectorObject
{
VectorRectangle(int x, int y, int width, int height)
{
lines.emplace_back(Line{ Point{x, y}, Point{x + width, y} });
lines.emplace_back(Line{ Point{x + width, y}, Point{x + width, y + height} });
lines.emplace_back(Line{ Point{x, y}, Point{x, y + height} });
lines.emplace_back(Line{ Point{x, y + height}, Point{x + width, y + height} });
}

std::vector<Line>::iterator begin() override
{
return lines.begin();
}

std::vector<Line>::iterator end() override
{
return lines.end();
}

private:
std::vector<Line> lines;
};

void DrawPoints(/*std::CPaintDC& dc, */std::vector<Point>::iterator start,
std::vector<Point>::iterator end)
{
for (auto i = start; i != end; ++i)
std::cout << i->x << " " << i->y << std::endl;
}

struct LineToPointCachingAdapter
{
typedef std::vector<Point> Points;

LineToPointCachingAdapter(Line& line)
{
Points points;

static boost::hash<Line> hash;
line_hash = hash_value(line);

if (cache.find(line_hash) != cache.end())
return;

int left = std::min(line.start.x, line.end.x);
int right = std::max(line.start.x, line.end.x);
int top = std::min(line.start.y, line.end.y);
int bottom = std::max(line.start.y, line.end.y);
int dx = right - left;
int dy = line.end.y - line.start.y;

if (dx == 0)
{
for (int y = top; y <= bottom; ++y)
{
points.emplace_back(Point{left, y});
}
}
else if (dy == 0)
{
for (int x = left; x <= right; ++x)
{
points.emplace_back(Point{x, top});
}
}

cache[line_hash] = points;
}

virtual Points::iterator begin() { return cache[line_hash].begin(); };
virtual Points::iterator end() { return cache[line_hash].end(); };

private:
//static
size_t line_hash;
//static
std::map<size_t, Points> cache;
};

int main(void)
{

std::vector<std::shared_ptr<VectorObject>> vectorObjects{
std::make_shared<VectorRectangle>(10, 10, 100, 100),
std::make_shared<VectorRectangle>(30, 30, 60, 60)
};

/*
for (const auto& obj: vectorObjects)
{
for (const auto& line: *obj)
{
LineToPointAdapter lpo{ line };
DrawPoints(lpo.begin(), lpo.end());
}
}
*/

std::vector<Point> points;

for (auto& o : vectorObjects)
{
for (auto& l : *o)
{
LineToPointCachingAdapter lpo{ l };
for (auto& p : lpo)
points.push_back(p);
}
}

DrawPoints(points.begin(), points.end());

return 0;
}

6.4 双向转化器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <iostream>
#include <string>
#include <exception>
#include <limits>

template <typename TFrom, typename TTo> class Converter
{
public:
virtual TTo Convert(const TFrom& from) = 0;
virtual TFrom ConvertBack(const TTo& to) = 0;
};

class IntToStringConverter : Converter<int, std::string>
{
public:
std::string Convert(const int& from) override
{
return std::to_string(from);
}
int ConvertBack(const std::string& to) override
{
int result;
try {
result = stoi(to);
}
catch(...)
{
return std::numeric_limits<int>::min();
}
//return result;
}
};

int main(void)
{
IntToStringConverter converter;
std::cout << converter.Convert(123) << std::endl;
std::cout << converter.ConvertBack("456") << std::endl;
std::cout << converter.ConvertBack("xyz") << std::endl;
return 0;
}