Re: [Boost-bugs] [Boost C++ Libraries] #5561: error on calculating interval_map intersection

Subject: Re: [Boost-bugs] [Boost C++ Libraries] #5561: error on calculating interval_map intersection
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2011-05-31 13:19:23


#5561: error on calculating interval_map intersection
------------------------------+---------------------------------------------
  Reporter: denis@… | Owner: jofaber
      Type: Bugs | Status: closed
 Milestone: Boost 1.47.0 | Component: ICL
   Version: Boost 1.46.1 | Severity: Problem
Resolution: invalid | Keywords:
------------------------------+---------------------------------------------

Comment (by denis@…):

 You solution is nice, but it not only enables set semantic but allows Icl
 to assume that codomain is an iterable container. And Icl uses iteration
 to perform some operations (for example {{{ operator^() }}} ).
 What I want is to have a codomain with set semantic without exposing its
 internals. It might have a container inside but also might not have. One
 example of such codomain is bool (or fixed-length array of bool). Another
 is AST tree.
 Below is code of exampled MySettic which exposes its
 intersection/union/difference interface but not the iteration interface.
 What is the recommended way to use it as a interval_map's codomain?

 {{{
 class MySettic {
   uint32_t set_;
   friend std::ostream& operator <<(std::ostream&, const MySettic&);
 public:
   MySettic() {}

   MySettic(int a, int b) {
     set_ = (1<<a) | (1<<b);
   }

   bool operator == (const MySettic& rhs) const { return set_ == rhs.set_;
 }

   MySettic& operator &= (const MySettic& rhs){
     set_ &= rhs.set_;
     return *this ;
   };
   MySettic& operator -= (const MySettic& rhs){
     set_ &= ~rhs.set_;
     return *this ;
   };
   MySettic& operator ^= (const MySettic& rhs){
     set_ ^= rhs.set_;
     return *this ;
   };
   MySettic& operator += (const MySettic& rhs){
     set_ |= rhs.set_;
     return *this ;
   };
 };
 std::ostream& operator <<(std::ostream& o, const MySettic& ms) {
   bool needspace=false;
   for(int i=0; i<32; i++)
     if(ms.set_ & (1<<i)) {
       if(needspace++) o << " ";
       o << i;
     }
   return o;
 }

 class fmt {
   std::ostringstream ss;
  public:
   operator std::ostringstream&() {return ss;}
   operator std::string() const {return ss.str();}
   template<typename T> fmt& operator<<(T const& v) {ss<<v; return *this;}
 };

 TEST(IntervalMap, MyCodomainSetSemantic) {
   MySettic s1(1,6), s2(1,12), s3;

 #ifdef TMP_FIX // it solves the issue partially, '|' '&' '-' work, but '^'
 fails
   icl::interval_map<int, MySettic,
     icl::partial_absorber, // default
     ICL_COMPARE_INSTANCE(std::less, DomainT), // default
     ICL_COMBINE_INSTANCE(icl::inplace_plus, MySettic), // default
     ICL_SECTION_INSTANCE(icl::inplace_et, MySettic)
> m1, m2;
 #else
   icl::interval_map<int, MySettic> m1, m2;
 #endif
   m1.add(make_pair(icl::interval<int>::closed(1,10), s1));
   m2.add(make_pair(icl::interval<int>::closed(5,15), s2));

   EXPECT_EQ("1 6 12", std::string(fmt() << ((s3=s1)+=s2)));
   EXPECT_EQ("1", std::string(fmt() << ((s3=s1)&=s2)));
   EXPECT_EQ("6", std::string(fmt() << ((s3=s1)-=s2)));
   EXPECT_EQ("6 12", std::string(fmt() << ((s3=s1)^=s2)));

   EXPECT_EQ("{([1,5)->1 6)([5,10]->1 6 12)((10,15]->1 12)}",
 std::string(fmt() << (m1|m2)));
   EXPECT_EQ("{([5,10]->1)}",
 std::string(fmt() << (m1&m2)));
   EXPECT_EQ("{([1,5)->1 6)([5,10]->6)}",
 std::string(fmt() << (m1-m2)));
   EXPECT_EQ("{([1,5)->1 6)([5,10]->6 12)((10,15]->1 12)}",
 std::string(fmt() << (m1^m2))); // wrong with TMP_FIX
 }

 }}}

-- 
Ticket URL: <https://svn.boost.org/trac/boost/ticket/5561#comment:3>
Boost C++ Libraries <http://www.boost.org/>
Boost provides free peer-reviewed portable C++ source libraries.

This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:06 UTC