
On 22/02/11 20:03, Joachim Faulhaber wrote:
2011/2/22 John Reid
I have started to use statically bounded intervals and am finding more compilation issues. For example with finding elements in a map:
#define BOOST_ICL_USE_STATIC_BOUNDED_INTERVALS #include
void f() { namespace icl = ::boost::icl; icl::interval_map< float, int>().find( 0 ); }
This compiles without the #define but fails on static intervals.
This is on purpose. The reason is that we can not represent a single element x using a right-open interval [x,?) of continuous values. right_open_interval is the default for statically bounded intervals, if BOOST_ICL_USE_STATIC_BOUNDED_INTERVALS is defined. In order to use find on an interval_map we have to construct an interval that represents a single element (internally). This is not possible in the logic of the ICL so this code won't compile.
Nevertheless, users will expect to be able to locate elements in sets. How should they do this? Does icl::contains( icl::interval_set< int >(), 0 ); compile, but icl::contains( icl::interval_set< float >(), 0. ); does not for the same reason?
interval_map::find is a pretty late addition to ITL/ICL, because using find in the STL way makes little sense on interval containers most of the time. We can not "find" an large interval in an icl::interval_set of small intervals.
{[0,2),[5,7)}.find([0,9))
If we cannot find the large interval, isn't the end() iterator a suitable return value to suggest it was not in the set/map?
The generalization of find is intersection. And the following function calls compile for statically bounded right-open intervals of continuous types:
#define BOOST_ICL_USE_STATIC_BOUNDED_INTERVALS #include
{ icl::interval_map< float, int> iclmap; icl::interval_map< float, int> found; add_intersection(found, iclmap, right_open_interval<float>(0,1)); add_intersection(found, icl::interval_map< float, int>(), right_open_interval<float>(0,1)); found = iclmap& right_open_interval<float>(0,1); found = icl::interval_map< float, int>() & right_open_interval<float>(0,1); }
I'm interested to hear reasons why the following don't compile when using static bounds: icl::add( icl::interval_set< int >(), 0 ); icl::add( icl::interval_set< int >(), icl::interval< int >::type( 0, 1 ) ); icl::interval_set< int >() += 0; icl::interval_set< int >() += icl::interval< int >::type( 0, 1 ); icl::subtract( icl::interval_set< int >(), 0 ); icl::subtract( icl::interval_set< int >(), icl::interval< int >::type( 0, 1 ) ); icl::interval_set< int >() -= 0; icl::interval_set< int >() -= icl::interval< int >::type( 0, 1 ); icl::interval_set< int >() &= 0; icl::interval_set< int >() &= icl::interval< int >::type( 0, 1 ); icl::interval_set< int >() ^= ( icl::interval< int >::type( 0, 1 ) ); They all seem reasonable operations to me. In particular, for a discrete domain, operations like icl::interval_set< int >() += 0 make sense to me. That is the following are equivalent: icl::interval_set< int >() += 0 icl::interval_set< int >() += icl::interval< int >::type( 0, 1 ); I agree the documentation needs to be more explicit about what is permissible. On a side note, I don't understand the rationale for having static bounds configured by #define whilst other aspects of intervals are parameterised using templates. I would have liked to have both types of interval in the same compilation unit. However I guess it must be too late to change this fundamental design choice. Regards, John.