A few ICL questions.
I'm new to ICL and have a few questions and a problem. Here is my test code which demonstrated (Windows, MSVC 2012):
// "icl_question.cpp"
#include "precomp.hpp"
#include <iostream>
#include <utility>
#include <functional>
#include
#include
#include
typedef boost::icl::closed_intervalboost::uint16_t interval_t;
// Based on the in "boost/icl/functors.hpp".
template <typename Type> struct inplace_assign
: public boost::icl::identity_based_inplace_combine<Type>
{
typedef inplace_assign<Type> type;
void operator()(Type& object, const Type& operand) const
{
object = operand;
}
};
// Why is the 7 template parameter not a template template parameter?
// The code in "boost/icl/detail/design_config.hpp" does not define the
// ICL_USE_INTERVAL_TEMPLATE_TYPE macro (I assume intentionally) which, if
// defined, would make it so.
typedef boost::icl::interval_map
<
boost::uint16_t,
const char*,
boost::icl::partial_absorber,
std::less,
inplace_assign,
boost::icl::inter_section,
interval_t
> map_t;
int main(int argc, char *argv[])
{
using namespace std;
map_t mem;
// The commented line two down is what I intend, but it asserts at
runtime.
// This one works.
mem += make_pair(interval_t(0, 0xfffe), "RAM");
//mem += make_pair(interval_t(0, 0xffff), "RAM");
mem += make_pair(interval_t(0xa000, 0xbfff), "Basic ROM");
cout << hex << mem << endl;
return 0;
}
The first question is about the aggregate on collision functionality. I would just like to replace. I have implemented *inplace_assign *which does this but it seems strange that this isn't included. Am I missing something here (I fear I may well be)? The second question is why* interval_map*'s 7th template parameter ( *Interval*) is not a template template parameter. The code in "boost/icl/detail/design_config.hpp" does not define the *ICL_USE_INTERVAL_TEMPLATE_TYPE *macro (I assume intentionally) which, if defined, would make it so. The third question is about a runtime error I'm getting in the above code. The comment in *main *shows the scenario. Basically if I use *0xffff *as the end of the first range I get an ASSERT at runtime whereas 0xfffe works fine. Finally, the documentation seems a little sparse on the function of the *Section* template parameter. Any clarification on that would be appreciated.
Hi Stephen,
2015-11-17 14:06 GMT+01:00 Stephen Hewitt
I'm new to ICL and have a few questions and a problem. Here is my test code which demonstrated (Windows, MSVC 2012):
// "icl_question.cpp"
#include "precomp.hpp"
#include <iostream>
#include <utility>
#include <functional>
#include
#include
#include
typedef boost::icl::closed_intervalboost::uint16_t interval_t;
// Based on the in "boost/icl/functors.hpp".
template <typename Type> struct inplace_assign
: public boost::icl::identity_based_inplace_combine<Type>
{
typedef inplace_assign<Type> type;
void operator()(Type& object, const Type& operand) const
{
object = operand;
}
};
// Why is the 7 template parameter not a template template parameter?
// The code in "boost/icl/detail/design_config.hpp" does not define the
// ICL_USE_INTERVAL_TEMPLATE_TYPE macro (I assume intentionally) which, if
// defined, would make it so.
typedef boost::icl::interval_map
<
boost::uint16_t,
const char*,
boost::icl::partial_absorber,
std::less,
inplace_assign,
boost::icl::inter_section,
interval_t
> map_t;
int main(int argc, char *argv[])
{
using namespace std;
map_t mem;
// The commented line two down is what I intend, but it asserts at
runtime.
// This one works.
mem += make_pair(interval_t(0, 0xfffe), "RAM");
//mem += make_pair(interval_t(0, 0xffff), "RAM");
mem += make_pair(interval_t(0xa000, 0xbfff), "Basic ROM");
cout << hex << mem << endl;
return 0;
}
The first question is about the aggregate on collision functionality. I would just like to replace. I have implemented *inplace_assign *which does this but it seems strange that this isn't included. Am I missing something here (I fear I may well be)?
Interval_maps of the icl are not only containers but also aggregation machines. So the default of aggregation functors are "addition" of associated elements and its inversion "subtraction". Other functors are provided for other kinds of aggregation. The functor inplace_identity results, when instantiated in the behavior of std::maps that keep their values on insertion of values for already inserted keys. You will get the same semantics using the member function insert. The functions to just "set" or "overwrite" values is available as member function set. See http://www.boost.org/doc/libs/1_59_0/libs/icl/doc/html/boost_icl/function_re... . Adding the "set" or "replace" functionality to the library via functor would be an addition that makes sense. But you can use the icl pretty well without it. Also you can add the functor yourself to your code base when you would like to use it as you just demonstrated.
The second question is why* interval_map*'s 7th template parameter ( *Interval*) is not a template template parameter. The code in "boost/icl/detail/design_config.hpp" does not define the *ICL_USE_INTERVAL_TEMPLATE_TYPE *macro (I assume intentionally) which, if defined, would make it so.
It needs to be a type. Otherwise the library would not be able to use user defined non-generic interval types. See also http://www.boost.org/doc/libs/1_59_0/libs/icl/doc/html/boost_icl/examples/cu...
The third question is about a runtime error I'm getting in the above code. The comment in *main *shows the scenario. Basically if I use *0xffff *as the end of the first range I get an ASSERT at runtime whereas 0xfffe works fine.
You can use icl interval containers with limited integral numeric domain-types safely on intervals using values from ++std::min<T>() to --std::max<T>(): Two values less. So if you want to manage a domain of values like in your example, you'd need to use a larger value type. It is possible to make the code handle those corner cases correctly (yet not trivial, since it is generic code). For achieving that the most frequently called functions would all need to make additional checks making the code ugly and more slowly. And yes, this information should be added to the documentation.
Finally, the documentation seems a little sparse on the function of the *Section* template parameter. Any clarification on that would be appreciated.
May be you'll find these sections helpful. http://www.boost.org/doc/libs/1_59_0/libs/icl/doc/html/boost_icl/semantics/c... http://www.boost.org/doc/libs/1_59_0/libs/icl/doc/html/boost_icl/semantics/q... Cheers, Joachim
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
-- Interval Container Library [Boost.Icl] http://www.joachim-faulhaber.de
The third question is about a runtime error I'm getting in the above code. The comment in *main *shows the scenario. Basically if I use *0xffff *as the end of the first range I get an ASSERT at runtime whereas 0xfffe works fine.
You can use icl interval containers with limited integral numeric domain-types safely on intervals using values from ++std::min<T>() to --std::max<T>(): Two values less. So if you want to manage a domain of values like in your example, you'd need to use a larger value type. It is possible to make the code handle those corner cases correctly (yet not trivial, since it is generic code). For achieving that the most frequently called functions would all need to make additional checks making the code ugly and more slowly. And yes, this information should be added to the documentation.
Ok this assessment was premature ... and thank you for your patch. It fixes the problem and I have already pushed the changes. For other interval types and their corner cases I will write a few tests shortly. -- Interval Container Library [Boost.Icl] http://www.joachim-faulhaber.de
participants (2)
-
Joachim Faulhaber
-
Stephen Hewitt