The following code doesn't work:
typedef boost::icl::interval_set<unsigned> bi_list_type;
typedef bi_list_type::value_type iv_type;
std::vector<iv_type> y;
iv_type x; // how to initialize this?
for (auto i : y)
{
x = boost::icl::hull(x, i);
}
The problem is, that x
is default constructed and thus in the end 0 is always the lower bound of x. Is there any better way to use boost::icl::hull
? And if so, how could I know without asking here (the doc isn't helpful in this regard)?
(The std::vector
is only an example, the interval creation happens actually inside the loop).
"a better way to use boost::icl::hull"
That depends 100% on the desired goal.
"(the doc isn't helpful in this regard)"
The doc also doesn't know your goal; it only tells you operations you can use to reach the goal.
I don't know your goal, but to me it looks very much like it's working:
#include <boost/icl/interval_set.hpp>
#include <iostream>
namespace icl = boost::icl;
int main() {
using iv_type = icl::discrete_interval<unsigned int, std::less>;
iv_type h{};
for (auto& i : {
iv_type::open(0, 0),
iv_type::left_open(5, 8),
iv_type::right_open(4, 6),
iv_type::closed(6, 7),
}) {
std::cout << "h: " << h << " adding " << i << "\n";
h = hull(h, i);
}
std::cout << "h: " << h << "\n";
}
Prints
h: [) adding ()
h: [) adding (5,8]
h: (5,8] adding [4,6)
h: [4,8] adding [6,7]
h: [4,8]
Since you mentioned interval_set perhaps you can do better:
#include <boost/icl/interval_set.hpp>
#include <iostream>
namespace icl = boost::icl;
int main() {
using set = icl::interval_set<unsigned int>;
using ival = set::value_type;
auto s = set{};
s.add(ival::open(0, 0));
s.add(ival::left_open(5, 8));
s.add(ival::right_open(4, 6));
s.add(ival::closed(6, 7));
std::cout << "hull: " << hull(s) << "\n";
}
Printing
hull: [4,8]
Due to the orderedness of the set this does something different, I think. Which may or may not be what you want depending on the meaning/goal.
If you really want the "left-fold" behaviour in sequence, but can't have an initializer like [)
or [min(), max())
then perhaps write it as a left-fold:
#include <algorithm>
#include <boost/icl/interval_set.hpp>
#include <iostream>
#include <numeric>
namespace icl = boost::icl;
int main() {
using iv_type = icl::discrete_interval<unsigned int, std::less>;
std::vector v{
iv_type::open(0, 0),
iv_type::left_open(5, 8),
iv_type::right_open(4, 6),
iv_type::closed(6, 7),
};
if (v.size()>0) {
std::cout
<< "h: "
<< std::accumulate(begin(v) + 1, end(v), v.front(),
[](auto a, auto const& b) {
return icl::hull(std::move(a), b);
})
<< "\n";
}
}
Which for our simple data still prints
h: [4,8]