1 // Boost.Geometry (aka GGL, Generic Geometry Library)
2
3 // Copyright (c) 2020 Barend Gehrels, Amsterdam, the Netherlands.
4
5 // Use, modification and distribution is subject to the Boost Software License,
6 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
7 // http://www.boost.org/LICENSE_1_0.txt)
8
9
10 #ifndef GEOMETRY_TEST_COUNT_SET_HPP
11 #define GEOMETRY_TEST_COUNT_SET_HPP
12
13 #include <boost/foreach.hpp>
14
15 #include <set>
16 #include <ostream>
17
18 // Structure to manage expectations: sometimes the output might have one or
19 // two rings, both are fine.
20 struct count_set
21 {
count_setcount_set22 count_set()
23 {
24 }
25
count_setcount_set26 count_set(int value)
27 {
28 if (value >= 0)
29 {
30 m_values.insert(static_cast<std::size_t>(value));
31 }
32 else
33 {
34 std::cout << "EMPTY" << std::endl;
35 }
36 }
37
count_setcount_set38 count_set(std::size_t value1, std::size_t value2)
39 {
40 m_values.insert(value1);
41 m_values.insert(value2);
42 }
43
emptycount_set44 bool empty() const { return m_values.empty(); }
45
hascount_set46 bool has(std::size_t value) const
47 {
48 return m_values.count(value) > 0;
49 }
50
operator <<(std::ostream & os,const count_set & s)51 friend std::ostream &operator<<(std::ostream &os, const count_set& s)
52 {
53 os << "{";
54 BOOST_FOREACH(std::size_t const& value, s.m_values)
55 {
56 os << " " << value;
57 }
58 os << "}";
59 return os;
60 }
61
operator +count_set62 count_set operator+(const count_set& a) const
63 {
64 count_set result;
65 result.m_values = combine(this->m_values, a.m_values);
66 return result;
67 }
68
69 private :
70 typedef std::set<std::size_t> set_type;
71 set_type m_values;
72
combinecount_set73 set_type combine(const set_type& a, const set_type& b) const
74 {
75 set_type result;
76 if (a.size() == 1 && b.size() == 1)
77 {
78 // The common scenario, both have one value
79 result.insert(*a.begin() + *b.begin());
80 }
81 else if (a.size() > 1 && b.size() == 1)
82 {
83 // One of them is optional, add the second
84 BOOST_FOREACH(std::size_t const& value, a)
85 {
86 result.insert(value + *b.begin());
87 }
88 }
89 else if (b.size() > 1 && a.size() == 1)
90 {
91 return combine(b, a);
92 }
93 // Else either is empty, or both have values and should be specified
94 return result;
95 }
96 };
97
ignore_count()98 inline count_set ignore_count()
99 {
100 return count_set();
101 }
102
optional()103 inline count_set optional()
104 {
105 return count_set(0, 1);
106 }
107
108 #endif // GEOMETRY_TEST_COUNT_SET_HPP
109