Commits

Anonymous committed 52ced07

dr81: #i117446# fix return value of interval_(map|set)::insert, rework of unit tests to take return values into account

Comments (0)

Files changed (4)

o3tl/inc/o3tl/interval_map.hxx

     inline const_iterator insert( integer_type nKey, const mapped_type& rData ) { return insert( interval_type( nKey, nKey ), rData ); }
     /** Inserts the passed data object at the passed interval. */
     const_iterator insert( const interval_type& rKey, const mapped_type& rData );
+    /** Inserts the passed data object at the passed interval. */
+    template< typename IntervalType >
+    inline const_iterator insert( const IntervalType& rKey, const mapped_type& rData ) { return insert( interval_type( rKey.first, rKey.second ), rData ); }
+
     /** Inserts the passed value, consisting of interval and data object. */
     inline const_iterator insert( const value_type& rValue ) { return insert( rValue.first, rValue.second ); }
-
-    /** Inserts the passed data object at the passed key or interval. */
-    template< typename IntervalType >
-    inline const_iterator insert( const IntervalType& rKey, const mapped_type& rData ) { return insert( interval_type( rKey.first, rKey.second ), rData ); }
-    /** Inserts the passed value, consisting of key or interval, and data object. */
+    /** Inserts the passed value, consisting of interval and data object. */
     template< typename ValueType >
     inline const_iterator insert( const ValueType& rValue ) { return insert( rValue.first, rValue.second ); }
+
     /** Inserts all elements in the passed range. InputIterator must
         dereference to value_type. */
     template< typename InputIterator >
     }
 
     // remove all elements covered by the new interval
-    maElements.erase( aIt + 1, aIt2 );
-    return aIt;
+    return maElements.erase( aIt + 1, aIt2 ) - 1;
 }
 
 template< typename IntType, typename MappedType, typename MappedComp, typename AllocType > template< typename InputIterator >

o3tl/inc/o3tl/interval_set.hxx

     inline const_iterator insert( integer_type nValue ) { return insert( interval_type( nValue, nValue ) ); }
     /** Inserts the passed interval into the set. */
     const_iterator insert( const interval_type& rInt );
-
     /** Inserts the passed interval into the set. */
     template< typename IntervalType >
     inline const_iterator insert( const IntervalType& rInt ) { return insert( interval_type( rInt.first, rInt.second ) ); }
+
     /** Inserts all elements in the passed range. InputIterator must
         dereference to integer_type or to any pair of IntType. */
     template< typename InputIterator >
     }
 
     // remove all elements covered by the new interval
-    maElements.erase( aIt + 1, aIt2 );
-    return aIt;
+    return maElements.erase( aIt + 1, aIt2 ) - 1;
 }
 
 template< typename IntType, typename AllocType > template< typename InputIterator >

o3tl/qa/test-interval_map.cxx

 
 // -----------------------------------------------------------------------------
 
-struct Triple { int first; int second; int third; };
+namespace {
+
+typedef ::o3tl::interval_map< int, int > map_type;
+
+bool next_int( int& value, const char*& chars )
+{
+    if( !*chars ) return false;
+    value = atoi( chars );
+    while( *chars && *chars != ',' ) ++chars;
+    if( *chars ) ++chars;
+    return true;
+}
+
+bool check_map( const map_type& map, const char* contents )
+{
+    map_type::const_iterator it = map.begin(), itend = map.end();
+    while( it != itend )
+    {
+        map_type::value_type value;
+        if( !next_int( value.first.first, contents ) || !next_int( value.first.second, contents ) || !next_int( value.second, contents ) || (value != *it ) )
+            return false;
+        ++it;
+    }
+    return (it == itend) && !*contents;
+}
+
+} // namespace
+
+// -----------------------------------------------------------------------------
 
 class interval_map_test : public CppUnit::TestFixture
 {
     void test();
 
 private:
-    typedef ::o3tl::interval_map< int, int > map_type;
-
-    void check_map( const map_type& map, const Triple* triples, size_t len, int line );
-
     CPPUNIT_TEST_SUITE( interval_map_test );
     CPPUNIT_TEST( test );
     CPPUNIT_TEST_SUITE_END();
 
 void interval_map_test::test()
 {
+#define CHECK_ITVALUE( map, it, value ) \
+    CPPUNIT_ASSERT_MESSAGE( "checking iterator", (it != map.end()) && (it->first.first == value) )
+
+#define CHECK_ITEND( map, it ) \
+    CPPUNIT_ASSERT_MESSAGE( "checking iterator end", it == map.end() )
+
+#define CHECK_CONTENTS( map, contents ) \
+    CPPUNIT_ASSERT_MESSAGE( "checking map contents", check_map( map, contents ) )
+
+#define CHECK_ITVALUE_CONTENTS( map, it, value, contents ) \
+    CHECK_ITVALUE( map, it, value ); CHECK_CONTENTS( map, contents )
+
+#define CHECK_ITEND_CONTENTS( map, it, contents ) \
+    CHECK_ITEND( map, it ); CHECK_CONTENTS( map, contents )
+
     map_type map;
-    CPPUNIT_ASSERT_MESSAGE( "empty", map.empty() );
-    typedef map_type::interval_type interval;
+    typedef map_type::interval_type i;
     map_type::const_iterator it;
 
-#define CALL_CHECK( map, triples ) check_map( map, triples, sizeof(triples)/sizeof(Triple), __LINE__ )
+    CPPUNIT_ASSERT_MESSAGE( "empty", map.empty() );
 
     // insert new ranges
 
-    static const Triple triples1[] = { {20,20,1} };
-    map.insert( 20, 1 ); CALL_CHECK( map, triples1 );
-
-    static const Triple triples2[] = { {20,20,1},{30,39,1} };
-    map.insert( interval( 30, 39 ), 1 ); CALL_CHECK( map, triples2 );
-
-    static const Triple triples3[] = { {0,1,1},{20,20,1},{30,39,1} };
-    map.insert( interval( 0, 1 ), 1 ); CALL_CHECK( map, triples3 );
-
-    static const Triple triples4[] = { {0,1,1},{5,7,1},{20,20,1},{30,39,1} };
-    map.insert( interval( 5, 7 ), 1 ); CALL_CHECK( map, triples4 );
+    it = map.insert( 20, 1 );       CHECK_ITVALUE_CONTENTS( map, it, 20, "20,20,1" );
+    it = map.insert( i(30,39), 1 ); CHECK_ITVALUE_CONTENTS( map, it, 30, "20,20,1,30,39,1" );
+    it = map.insert( i(0,1), 1 );   CHECK_ITVALUE_CONTENTS( map, it, 0, "0,1,1,20,20,1,30,39,1" );
+    it = map.insert( i(5,7 ), 1 );  CHECK_ITVALUE_CONTENTS( map, it, 5, "0,1,1,5,7,1,20,20,1,30,39,1" );
 
     // insert into existing range
 
-    map.insert( 5, 1 ); CALL_CHECK( map, triples4 );
-    map.insert( 6, 1 ); CALL_CHECK( map, triples4 );
-    map.insert( 7, 1 ); CALL_CHECK( map, triples4 );
-    map.insert( interval( 5, 6 ), 1 ); CALL_CHECK( map, triples4 );
-    map.insert( interval( 6, 7 ), 1 ); CALL_CHECK( map, triples4 );
-    map.insert( interval( 5, 7 ), 1 ); CALL_CHECK( map, triples4 );
+    it = map.insert( 5, 1 );        CHECK_ITVALUE_CONTENTS( map, it, 5, "0,1,1,5,7,1,20,20,1,30,39,1" );
+    it = map.insert( 6, 1 );        CHECK_ITVALUE_CONTENTS( map, it, 5, "0,1,1,5,7,1,20,20,1,30,39,1" );
+    it = map.insert( 7, 1 );        CHECK_ITVALUE_CONTENTS( map, it, 5, "0,1,1,5,7,1,20,20,1,30,39,1" );
+    it = map.insert( i(5,6), 1 );   CHECK_ITVALUE_CONTENTS( map, it, 5, "0,1,1,5,7,1,20,20,1,30,39,1" );
+    it = map.insert( i(6,7), 1 );   CHECK_ITVALUE_CONTENTS( map, it, 5, "0,1,1,5,7,1,20,20,1,30,39,1" );
+    it = map.insert( i(5,7), 1 );   CHECK_ITVALUE_CONTENTS( map, it, 5, "0,1,1,5,7,1,20,20,1,30,39,1" );
 
     // expand existing range
 
-    static const Triple triples11[] = { {0,1,1},{5,7,1},{19,20,1},{30,39,1} };
-    map.insert( interval( 19, 20 ), 1 ); CALL_CHECK( map, triples11 );
-
-    static const Triple triples12[] = { {0,1,1},{5,7,1},{19,22,1},{30,39,1} };
-    map.insert( interval( 20, 22 ), 1 ); CALL_CHECK( map, triples12 );
-
-    static const Triple triples13[] = { {0,1,1},{5,7,1},{17,24,1},{30,39,1} };
-    map.insert( interval( 17, 24 ), 1 ); CALL_CHECK( map, triples13 );
-
-    static const Triple triples14[] = { {0,1,1},{5,7,1},{15,24,1},{30,39,1} };
-    map.insert( interval( 15, 16 ), 1 ); CALL_CHECK( map, triples14 );
-
-    static const Triple triples15[] = { {0,1,1},{5,7,1},{15,27,1},{30,39,1} };
-    map.insert( interval( 25, 27 ), 1 ); CALL_CHECK( map, triples15 );
+    it = map.insert( i(19,20), 1 ); CHECK_ITVALUE_CONTENTS( map, it, 19, "0,1,1,5,7,1,19,20,1,30,39,1" );
+    it = map.insert( i(20,22), 1 ); CHECK_ITVALUE_CONTENTS( map, it, 19, "0,1,1,5,7,1,19,22,1,30,39,1" );
+    it = map.insert( i(17,24), 1 ); CHECK_ITVALUE_CONTENTS( map, it, 17, "0,1,1,5,7,1,17,24,1,30,39,1" );
+    it = map.insert( i(15,16), 1 ); CHECK_ITVALUE_CONTENTS( map, it, 15, "0,1,1,5,7,1,15,24,1,30,39,1" );
+    it = map.insert( i(25,27), 1 ); CHECK_ITVALUE_CONTENTS( map, it, 15, "0,1,1,5,7,1,15,27,1,30,39,1" );
 
     // find, find_bound
 
-    CPPUNIT_ASSERT_MESSAGE( "find", (it = map.find( -2 )) == map.end() );
-    CPPUNIT_ASSERT_MESSAGE( "find", (it = map.find( -1 )) == map.end() );
-    CPPUNIT_ASSERT_MESSAGE( "find", ((it = map.find( 0 )) != map.end()) && (it->first.first == 0) );
-    CPPUNIT_ASSERT_MESSAGE( "find", ((it = map.find( 1 )) != map.end()) && (it->first.first == 0) );
-    CPPUNIT_ASSERT_MESSAGE( "find", (it = map.find( 2 )) == map.end() );
-    CPPUNIT_ASSERT_MESSAGE( "find", (it = map.find( 3 )) == map.end() );
-    CPPUNIT_ASSERT_MESSAGE( "find", (it = map.find( 4 )) == map.end() );
-    CPPUNIT_ASSERT_MESSAGE( "find", ((it = map.find( 5 )) != map.end()) && (it->first.first == 5) );
-    CPPUNIT_ASSERT_MESSAGE( "find", ((it = map.find( 39 )) != map.end()) && (it->first.first == 30) );
-    CPPUNIT_ASSERT_MESSAGE( "find", (it = map.find( 40 )) == map.end() );
-    CPPUNIT_ASSERT_MESSAGE( "find", (it = map.find( 41 )) == map.end() );
+    it = map.find( -2 );            CHECK_ITEND( map, it );
+    it = map.find( -1 );            CHECK_ITEND( map, it );
+    it = map.find( 0 );             CHECK_ITVALUE( map, it, 0 );
+    it = map.find( 1 );             CHECK_ITVALUE( map, it, 0 );
+    it = map.find( 2 );             CHECK_ITEND( map, it );
+    it = map.find( 3 );             CHECK_ITEND( map, it );
+    it = map.find( 4 );             CHECK_ITEND( map, it );
+    it = map.find( 5 );             CHECK_ITVALUE( map, it, 5 );
+    it = map.find( 39 );            CHECK_ITVALUE( map, it, 30 );
+    it = map.find( 40 );            CHECK_ITEND( map, it );
+    it = map.find( 41 );            CHECK_ITEND( map, it );
 
-    CPPUNIT_ASSERT_MESSAGE( "find_bound", ((it = map.find_bound( -2 )) != map.end()) && (it->first.first == 0) );
-    CPPUNIT_ASSERT_MESSAGE( "find_bound", ((it = map.find_bound( -1 )) != map.end()) && (it->first.first == 0) );
-    CPPUNIT_ASSERT_MESSAGE( "find_bound", ((it = map.find_bound( 0 )) != map.end()) && (it->first.first == 0) );
-    CPPUNIT_ASSERT_MESSAGE( "find_bound", ((it = map.find_bound( 1 )) != map.end()) && (it->first.first == 0) );
-    CPPUNIT_ASSERT_MESSAGE( "find_bound", ((it = map.find_bound( 2 )) != map.end()) && (it->first.first == 5) );
-    CPPUNIT_ASSERT_MESSAGE( "find_bound", ((it = map.find_bound( 3 )) != map.end()) && (it->first.first == 5) );
-    CPPUNIT_ASSERT_MESSAGE( "find_bound", ((it = map.find_bound( 4 )) != map.end()) && (it->first.first == 5) );
-    CPPUNIT_ASSERT_MESSAGE( "find_bound", ((it = map.find_bound( 5 )) != map.end()) && (it->first.first == 5) );
-    CPPUNIT_ASSERT_MESSAGE( "find_bound", ((it = map.find_bound( 39 )) != map.end()) && (it->first.first == 30) );
-    CPPUNIT_ASSERT_MESSAGE( "find_bound", (it = map.find_bound( 40 )) == map.end() );
-    CPPUNIT_ASSERT_MESSAGE( "find_bound", (it = map.find_bound( 41 )) == map.end() );
+    it = map.find_bound( -2 );      CHECK_ITVALUE( map, it, 0 );
+    it = map.find_bound( -1 );      CHECK_ITVALUE( map, it, 0 );
+    it = map.find_bound( 0 );       CHECK_ITVALUE( map, it, 0 );
+    it = map.find_bound( 1 );       CHECK_ITVALUE( map, it, 0 );
+    it = map.find_bound( 2 );       CHECK_ITVALUE( map, it, 5 );
+    it = map.find_bound( 3 );       CHECK_ITVALUE( map, it, 5 );
+    it = map.find_bound( 4 );       CHECK_ITVALUE( map, it, 5 );
+    it = map.find_bound( 5 );       CHECK_ITVALUE( map, it, 5 );
+    it = map.find_bound( 39 );      CHECK_ITVALUE( map, it, 30 );
+    it = map.find_bound( 40 );      CHECK_ITEND( map, it );
+    it = map.find_bound( 41 );      CHECK_ITEND( map, it );
 
     // make intersection
 
-    static const Triple triples_int[] = { {6,7,1},{15,27,1},{30,33,1} };
-    map_type map2 = map.make_intersection( interval( 6, 33 ) ); CALL_CHECK( map2, triples_int );
+    map_type map2 = map.make_intersection( i(6,33) );
+    CHECK_CONTENTS( map2, "6,7,1,15,27,1,30,33,1" );
 
-    // range c'tor, range insert, insert custom interval type
+    // range c'tor, range insert, insert custom types
 
     struct Pair { int first; int second; };
-    struct ValueType { Pair first; int second; };
+    struct ValueType { Pair first; short second; };
+    struct ValuePair { int first; short second; };
 
-    static const Triple triples15a[] = { {7,7,1},{15,26,1} };
-    static const ValueType init1[] = { {{7,7},1},{{15,26},1} };
-    map_type map3( init1, init1 + sizeof(init1)/sizeof(ValueType) ); CALL_CHECK( map3, triples15a );
+    static const ValueType init1[] = { {{7,7},1}, {{15,26},1} };
+    static const ValueType init2 = {{30,31},1};
+    static const ValuePair init3 = {32,1};
+    static const ValuePair init4[] = { {33,1},{6,1},{27,1} };
 
-    static const Triple triples15b[] = { {7,7,1},{15,26,1},{30,31,1} };
-    static const ValueType init2 = {{30,31},1};
-    map3.insert( init2 ); CALL_CHECK( map3, triples15b );
+    map_type map3( init1, init1 + sizeof(init1)/sizeof(ValueType) );
+    CHECK_CONTENTS( map3, "7,7,1,15,26,1" );
 
-    static const Triple triples15c[] = { {7,7,1},{15,26,1},{30,32,1} };
-    static const Pair init3 = {32,1};
-    map3.insert( init3 ); CALL_CHECK( map3, triples15c );
+    it = map3.insert( init2 );      CHECK_ITVALUE_CONTENTS( map3, it, 30, "7,7,1,15,26,1,30,31,1" );
+    it = map3.insert( init3 );      CHECK_ITVALUE_CONTENTS( map3, it, 30, "7,7,1,15,26,1,30,32,1" );
 
-    static const Pair init4[] = { {33,1},{6,1},{27,1} };
-    map3.insert( init4, init4 + sizeof(init4)/sizeof(Pair) ); CALL_CHECK( map3, triples_int );
+    map3.insert( init4, init4 + sizeof(init4)/sizeof(ValuePair) );
+    CHECK_CONTENTS( map3, "6,7,1,15,27,1,30,33,1" );
 
     // operator==
 
     CPPUNIT_ASSERT_MESSAGE( "operator==", map2 == map3 );
-    map3.insert( interval( 30, 33 ), 2 );
+    map3.insert( 35, 2 );
     CPPUNIT_ASSERT_MESSAGE( "operator!=", map2 != map3 );
-    map3.insert( interval( 30, 34 ), 1 );
+    map3.insert( 34, 1 );
     CPPUNIT_ASSERT_MESSAGE( "operator!=", map2 != map3 );
 
     // merge and overwrite
 
-    static const Triple triples16[] = { {0,8,1},{15,27,1},{30,39,1} };
-    map.insert( interval( 1, 8 ), 1 ); CALL_CHECK( map, triples16 );
-
-    static const Triple triples17[] = { {0,39,1} };
-    map.insert( interval( 9, 29 ), 1 ); CALL_CHECK( map, triples17 );
+    it = map.insert( i(1,8), 1 );   CHECK_ITVALUE_CONTENTS( map, it, 0, "0,8,1,15,27,1,30,39,1" );
+    it = map.insert( i(9,29), 1 );  CHECK_ITVALUE_CONTENTS( map, it, 0, "0,39,1" );
 
     // remove inside range
 
-    static const Triple triples18[] = { {0,9,1},{11,19,1},{21,29,1},{31,39,1} };
-    map.erase( 10 ); map.erase( 20 ); map.erase( 30 ); CALL_CHECK( map, triples18 );
-
-    static const Triple triples19[] = { {0,9,1},{11,19,1},{24,29,1},{31,39,1} };
-    map.erase( interval( 21, 23 ) ); CALL_CHECK( map, triples19 );
-
-    static const Triple triples20[] = { {0,9,1},{11,19,1},{24,26,1},{31,39,1} };
-    map.erase( interval( 27, 29 ) ); CALL_CHECK( map, triples20 );
-
-    static const Triple triples21[] = { {0,9,1},{11,19,1},{31,39,1} };
-    map.erase( interval( 24, 26 ) ); CALL_CHECK( map, triples21 );
+    it = map.erase( 10 );           CHECK_ITVALUE_CONTENTS( map, it, 11, "0,9,1,11,39,1" );
+    it = map.erase( 20 );           CHECK_ITVALUE_CONTENTS( map, it, 21, "0,9,1,11,19,1,21,39,1" );
+    it = map.erase( 30 );           CHECK_ITVALUE_CONTENTS( map, it, 31, "0,9,1,11,19,1,21,29,1,31,39,1" );
+    it = map.erase( i(21,23) );     CHECK_ITVALUE_CONTENTS( map, it, 24, "0,9,1,11,19,1,24,29,1,31,39,1" );
+    it = map.erase( i(27,29) );     CHECK_ITVALUE_CONTENTS( map, it, 31, "0,9,1,11,19,1,24,26,1,31,39,1" );
+    it = map.erase( i(24,26) );     CHECK_ITVALUE_CONTENTS( map, it, 31, "0,9,1,11,19,1,31,39,1" );
 
     // remove outside ranges
 
-    map.erase( -1 ); CALL_CHECK( map, triples21 );
-    map.erase( 10 ); CALL_CHECK( map, triples21 );
-    map.erase( interval( 20, 22 ) ); CALL_CHECK( map, triples21 );
-    map.erase( interval( 29, 30 ) ); CALL_CHECK( map, triples21 );
-    map.erase( interval( 20, 30 ) ); CALL_CHECK( map, triples21 );
-    map.erase( interval( 40, 41 ) ); CALL_CHECK( map, triples21 );
+    it = map.erase( -1 );           CHECK_ITVALUE_CONTENTS( map, it, 0, "0,9,1,11,19,1,31,39,1" );
+    it = map.erase( 10 );           CHECK_ITVALUE_CONTENTS( map, it, 11, "0,9,1,11,19,1,31,39,1" );
+    it = map.erase( i(20,22) );     CHECK_ITVALUE_CONTENTS( map, it, 31, "0,9,1,11,19,1,31,39,1" );
+    it = map.erase( i(29,30) );     CHECK_ITVALUE_CONTENTS( map, it, 31, "0,9,1,11,19,1,31,39,1" );
+    it = map.erase( i(20,30) );     CHECK_ITVALUE_CONTENTS( map, it, 31, "0,9,1,11,19,1,31,39,1" );
+    it = map.erase( i(40,41) );     CHECK_ITEND_CONTENTS( map, it, "0,9,1,11,19,1,31,39,1" );
 
     // remove in several ranges
 
-    static const Triple triples22[] = { {0,6,1},{13,19,1},{31,39,1} };
-    map.erase( interval( 7, 12 ) ); CALL_CHECK( map, triples22 );
-
-    static const Triple triples23[] = { {0,5,1},{33,39,1} };
-    map.erase( interval( 6, 32 ) ); CALL_CHECK( map, triples23 );
-
-    static const Triple triples24[] = { {0,0,1} };
-    map.erase( interval( 1, 44 ) ); CALL_CHECK( map, triples24 );
-
-    map.erase( interval( -1, 1 ) );
-    CPPUNIT_ASSERT_MESSAGE( "empty", map.empty() );
+    it = map.erase( i(7,12) );      CHECK_ITVALUE_CONTENTS( map, it, 13, "0,6,1,13,19,1,31,39,1" );
+    it = map.erase( i(6,32) );      CHECK_ITVALUE_CONTENTS( map, it, 33, "0,5,1,33,39,1" );
+    it = map.erase( i(1,44) );      CHECK_ITEND_CONTENTS( map, it, "0,0,1" );
+    it = map.erase( i(-1,1) );      CHECK_ITEND_CONTENTS( map, it, "" );
 
     // insert mixed data
 
-    map.insert( interval( 10, 19 ), 1 );
-    map.insert( interval( 30, 39 ), 1 );
-    map.insert( interval( 50, 59 ), 1 );
+    static const ValueType init5[] = { {{10,19},1}, {{30,39},1}, {{50,59},1} };
+    map.assign( init5, init5 + sizeof(init5)/sizeof(ValueType) );
 
-    static const Triple triples25[] = { {1,1,2},{10,19,1},{30,39,1},{50,59,1} };
-    map.insert( 1, 2 ); CALL_CHECK( map, triples25 );
-
-    static const Triple triples26[] = { {1,1,2},{10,19,1},{20,21,2},{30,39,1},{50,59,1} };
-    map.insert( interval( 20, 21 ), 2 ); CALL_CHECK( map, triples26 );
-
-    static const Triple triples27[] = { {1,1,2},{10,19,1},{20,21,2},{28,29,2},{30,39,1},{50,59,1} };
-    map.insert( interval( 28, 29 ), 2 ); CALL_CHECK( map, triples27 );
-
-    static const Triple triples28[] = { {1,1,2},{10,19,1},{20,21,2},{28,29,2},{30,39,1},{50,59,1},{60,60,2} };
-    map.insert( 60, 2 ); CALL_CHECK( map, triples28 );
-
-    static const Triple triples29[] = { {1,21,2},{28,29,2},{30,39,1},{50,59,1},{60,60,2} };
-    map.insert( interval( 2, 19 ), 2 ); CALL_CHECK( map, triples29 );
-
-    static const Triple triples30[] = { {1,21,2},{28,30,2},{31,39,1},{50,59,1},{60,60,2} };
-    map.insert( 30, 2 ); CALL_CHECK( map, triples30 );
-
-    static const Triple triples31[] = { {1,21,2},{28,30,2},{31,39,1},{50,58,1},{59,60,2} };
-    map.insert( 59, 2 ); CALL_CHECK( map, triples31 );
-
-    static const Triple triples32[] = { {1,21,2},{28,30,2},{31,39,1},{50,51,2},{52,58,1},{59,60,2} };
-    map.insert( interval( 50, 51 ), 2 ); CALL_CHECK( map, triples32 );
-
-    static const Triple triples33[] = { {1,21,2},{28,30,2},{31,37,1},{38,39,2},{50,51,2},{52,58,1},{59,60,2} };
-    map.insert( interval( 38, 39 ), 2 ); CALL_CHECK( map, triples33 );
-
-    static const Triple triples34[] = { {1,21,2},{28,30,2},{31,34,1},{35,35,2},{36,37,1},{38,39,2},{50,51,2},{52,58,1},{59,60,2} };
-    map.insert( 35, 2 ); CALL_CHECK( map, triples34 );
-
-    static const Triple triples35[] = { {1,21,2},{28,30,2},{31,34,1},{35,39,2},{50,51,2},{52,58,1},{59,60,2} };
-    map.insert( interval( 36, 37 ), 2 ); CALL_CHECK( map, triples35 );
-
-#undef CALL_CHECK
-}
-
-void interval_map_test::check_map( const map_type& map, const Triple* triples, size_t len, int line )
-{
-    const Triple* triplesend = triples + len;
-    map_type::const_iterator it = map.begin(), itend = map.end();
-    int index = 0;
-    char buffer[ 256 ];
-    while( (it != itend) || (triples != triplesend) )
-    {
-        bool itvalid = it != itend;
-        bool triplesvalid = triples != triplesend;
-        if( itvalid && triplesvalid )
-            sprintf( buffer, "line %d; failed: #%d; exp: (%d,%d,%d); found: (%d,%d,%d)", line, index, triples->first, triples->second, triples->third, it->first.first, it->first.second, it->second );
-        else if( itvalid )
-            sprintf( buffer, "line %d; failed: #%d; exp: [end]; found: (%d,%d,%d)", line, index, it->first.first, it->first.second, it->second );
-        else
-            sprintf( buffer, "line %d; failed: #%d; exp: (%d,%d,%d); found: [end]", line, index, triples->first, triples->second, triples->third );
-        CPPUNIT_ASSERT_MESSAGE( buffer, itvalid && triplesvalid && (it->first.first == triples->first) && (it->first.second == triples->second) && (it->second == triples->third) );
-        if( itvalid ) ++it;
-        if( triplesvalid ) ++triples;
-        ++index;
-    }
+    it = map.insert( 1, 2 );        CHECK_ITVALUE_CONTENTS( map, it, 1, "1,1,2,10,19,1,30,39,1,50,59,1" );
+    it = map.insert( i(20,21), 2 ); CHECK_ITVALUE_CONTENTS( map, it, 20, "1,1,2,10,19,1,20,21,2,30,39,1,50,59,1" );
+    it = map.insert( i(28,29), 2 ); CHECK_ITVALUE_CONTENTS( map, it, 28, "1,1,2,10,19,1,20,21,2,28,29,2,30,39,1,50,59,1" );
+    it = map.insert( 60, 2 );       CHECK_ITVALUE_CONTENTS( map, it, 60, "1,1,2,10,19,1,20,21,2,28,29,2,30,39,1,50,59,1,60,60,2" );
+    it = map.insert( i(2,19), 2 );  CHECK_ITVALUE_CONTENTS( map, it, 1, "1,21,2,28,29,2,30,39,1,50,59,1,60,60,2" );
+    it = map.insert( 30, 2 );       CHECK_ITVALUE_CONTENTS( map, it, 28, "1,21,2,28,30,2,31,39,1,50,59,1,60,60,2" );
+    it = map.insert( 59, 2 );       CHECK_ITVALUE_CONTENTS( map, it, 59, "1,21,2,28,30,2,31,39,1,50,58,1,59,60,2" );
+    it = map.insert( i(50,51), 2 ); CHECK_ITVALUE_CONTENTS( map, it, 50, "1,21,2,28,30,2,31,39,1,50,51,2,52,58,1,59,60,2" );
+    it = map.insert( i(38,39), 2 ); CHECK_ITVALUE_CONTENTS( map, it, 38, "1,21,2,28,30,2,31,37,1,38,39,2,50,51,2,52,58,1,59,60,2" );
+    it = map.insert( 35, 2 );       CHECK_ITVALUE_CONTENTS( map, it, 35, "1,21,2,28,30,2,31,34,1,35,35,2,36,37,1,38,39,2,50,51,2,52,58,1,59,60,2" );
+    it = map.insert( i(36,37), 2 ); CHECK_ITVALUE_CONTENTS( map, it, 35, "1,21,2,28,30,2,31,34,1,35,39,2,50,51,2,52,58,1,59,60,2" );
 }
 
 // -----------------------------------------------------------------------------

o3tl/qa/test-interval_set.cxx

 
 // -----------------------------------------------------------------------------
 
-struct Pair { int first; int second; };
+namespace {
+
+typedef ::o3tl::interval_set< int > set_type;
+
+bool next_int( int& value, const char*& chars )
+{
+    if( !*chars ) return false;
+    value = atoi( chars );
+    while( *chars && *chars != ',' ) ++chars;
+    if( *chars ) ++chars;
+    return true;
+}
+
+bool check_set( const set_type& set, const char* contents )
+{
+    set_type::const_iterator it = set.begin(), itend = set.end();
+    while( it != itend )
+    {
+        set_type::value_type value;
+        if( !next_int( value.first, contents ) || !next_int( value.second, contents ) || (value != *it ) )
+            return false;
+        ++it;
+    }
+    return (it == itend) && !*contents;
+}
+
+} // namespace
+
+// -----------------------------------------------------------------------------
 
 class interval_set_test : public CppUnit::TestFixture
 {
     void test();
 
 private:
-    typedef ::o3tl::interval_set< int > set_type;
-
-    void check_set( const set_type& set, const Pair* pairs, size_t len, int line );
-
     CPPUNIT_TEST_SUITE( interval_set_test );
     CPPUNIT_TEST( test );
     CPPUNIT_TEST_SUITE_END();
 
 void interval_set_test::test()
 {
+#define CHECK_ITVALUE( set, it, value ) \
+    CPPUNIT_ASSERT_MESSAGE( "checking iterator", (it != set.end()) && (it->first == value) )
+
+#define CHECK_ITEND( set, it ) \
+    CPPUNIT_ASSERT_MESSAGE( "checking iterator end", it == set.end() )
+
+#define CHECK_CONTENTS( set, contents ) \
+    CPPUNIT_ASSERT_MESSAGE( "checking set contents", check_set( set, contents ) )
+
+#define CHECK_ITVALUE_CONTENTS( set, it, value, contents ) \
+    CHECK_ITVALUE( set, it, value ); CHECK_CONTENTS( set, contents )
+
+#define CHECK_ITEND_CONTENTS( set, it, contents ) \
+    CHECK_ITEND( set, it ); CHECK_CONTENTS( set, contents )
+
     set_type set;
-    CPPUNIT_ASSERT_MESSAGE( "empty", set.empty() );
-    typedef set_type::interval_type interval;
+    typedef set_type::interval_type i;
     set_type::const_iterator it;
 
-#define CALL_CHECK( set, pairs ) check_set( set, pairs, sizeof(pairs)/sizeof(Pair), __LINE__ )
+    CPPUNIT_ASSERT_MESSAGE( "empty", set.empty() );
 
     // insert new ranges
 
-    static const Pair pairs1[] = { {20,20} };
-    set.insert( 20 ); CALL_CHECK( set, pairs1 );
-
-    static const Pair pairs2[] = { {20,20},{30,39} };
-    set.insert( interval( 30, 39 ) ); CALL_CHECK( set, pairs2 );
-
-    static const Pair pairs3[] = { {0,1},{20,20},{30,39} };
-    set.insert( interval( 0, 1 ) ); CALL_CHECK( set, pairs3 );
-
-    static const Pair pairs4[] = { {0,1},{5,7},{20,20},{30,39} };
-    set.insert( interval( 5, 7 ) ); CALL_CHECK( set, pairs4 );
+    it = set.insert( 20 );          CHECK_ITVALUE_CONTENTS( set, it, 20, "20,20" );
+    it = set.insert( i(30,39) );    CHECK_ITVALUE_CONTENTS( set, it, 30, "20,20,30,39" );
+    it = set.insert( i(0,1) );      CHECK_ITVALUE_CONTENTS( set, it, 0, "0,1,20,20,30,39" );
+    it = set.insert( i(5,7) );      CHECK_ITVALUE_CONTENTS( set, it, 5, "0,1,5,7,20,20,30,39" );
 
     // insert into existing range
 
-    set.insert( 5 ); CALL_CHECK( set, pairs4 );
-    set.insert( 6 ); CALL_CHECK( set, pairs4 );
-    set.insert( 7 ); CALL_CHECK( set, pairs4 );
-    set.insert( interval( 5, 6 ) ); CALL_CHECK( set, pairs4 );
-    set.insert( interval( 6, 7 ) ); CALL_CHECK( set, pairs4 );
-    set.insert( interval( 5, 7 ) ); CALL_CHECK( set, pairs4 );
+    it = set.insert( 5 );           CHECK_ITVALUE_CONTENTS( set, it, 5, "0,1,5,7,20,20,30,39" );
+    it = set.insert( 6 );           CHECK_ITVALUE_CONTENTS( set, it, 5, "0,1,5,7,20,20,30,39" );
+    it = set.insert( 7 );           CHECK_ITVALUE_CONTENTS( set, it, 5, "0,1,5,7,20,20,30,39" );
+    it = set.insert( i(5,6) );      CHECK_ITVALUE_CONTENTS( set, it, 5, "0,1,5,7,20,20,30,39" );
+    it = set.insert( i(6,7) );      CHECK_ITVALUE_CONTENTS( set, it, 5, "0,1,5,7,20,20,30,39" );
+    it = set.insert( i(5,7) );      CHECK_ITVALUE_CONTENTS( set, it, 5, "0,1,5,7,20,20,30,39" );
 
     // expand existing range
 
-    static const Pair pairs11[] = { {0,1},{5,7},{19,20},{30,39} };
-    set.insert( interval( 19, 20 ) ); CALL_CHECK( set, pairs11 );
-
-    static const Pair pairs12[] = { {0,1},{5,7},{19,22},{30,39} };
-    set.insert( interval( 20, 22 ) ); CALL_CHECK( set, pairs12 );
-
-    static const Pair pairs13[] = { {0,1},{5,7},{17,24},{30,39} };
-    set.insert( interval( 17, 24 ) ); CALL_CHECK( set, pairs13 );
-
-    static const Pair pairs14[] = { {0,1},{5,7},{15,24},{30,39} };
-    set.insert( interval( 15, 16 ) ); CALL_CHECK( set, pairs14 );
-
-    static const Pair pairs15[] = { {0,1},{5,7},{15,27},{30,39} };
-    set.insert( interval( 25, 27 ) ); CALL_CHECK( set, pairs15 );
+    it = set.insert( i(19,20) );    CHECK_ITVALUE_CONTENTS( set, it, 19, "0,1,5,7,19,20,30,39" );
+    it = set.insert( i(20,22) );    CHECK_ITVALUE_CONTENTS( set, it, 19, "0,1,5,7,19,22,30,39" );
+    it = set.insert( i(17,24) );    CHECK_ITVALUE_CONTENTS( set, it, 17, "0,1,5,7,17,24,30,39" );
+    it = set.insert( i(15,16) );    CHECK_ITVALUE_CONTENTS( set, it, 15, "0,1,5,7,15,24,30,39" );
+    it = set.insert( i(25,27) );    CHECK_ITVALUE_CONTENTS( set, it, 15, "0,1,5,7,15,27,30,39" );
 
     // find, find_bound
 
-    CPPUNIT_ASSERT_MESSAGE( "find", (it = set.find( -2 )) == set.end() );
-    CPPUNIT_ASSERT_MESSAGE( "find", (it = set.find( -1 )) == set.end() );
-    CPPUNIT_ASSERT_MESSAGE( "find", ((it = set.find( 0 )) != set.end()) && (it->first == 0) );
-    CPPUNIT_ASSERT_MESSAGE( "find", ((it = set.find( 1 )) != set.end()) && (it->first == 0) );
-    CPPUNIT_ASSERT_MESSAGE( "find", (it = set.find( 2 )) == set.end() );
-    CPPUNIT_ASSERT_MESSAGE( "find", (it = set.find( 3 )) == set.end() );
-    CPPUNIT_ASSERT_MESSAGE( "find", (it = set.find( 4 )) == set.end() );
-    CPPUNIT_ASSERT_MESSAGE( "find", ((it = set.find( 5 )) != set.end()) && (it->first == 5) );
-    CPPUNIT_ASSERT_MESSAGE( "find", ((it = set.find( 39 )) != set.end()) && (it->first == 30) );
-    CPPUNIT_ASSERT_MESSAGE( "find", (it = set.find( 40 )) == set.end() );
-    CPPUNIT_ASSERT_MESSAGE( "find", (it = set.find( 41 )) == set.end() );
+    it = set.find( -2 );            CHECK_ITEND( set, it );
+    it = set.find( -1 );            CHECK_ITEND( set, it );
+    it = set.find( 0 );             CHECK_ITVALUE( set, it, 0 );
+    it = set.find( 1 );             CHECK_ITVALUE( set, it, 0 );
+    it = set.find( 2 );             CHECK_ITEND( set, it );
+    it = set.find( 3 );             CHECK_ITEND( set, it );
+    it = set.find( 4 );             CHECK_ITEND( set, it );
+    it = set.find( 5 );             CHECK_ITVALUE( set, it, 5 );
+    it = set.find( 39 );            CHECK_ITVALUE( set, it, 30 );
+    it = set.find( 40 );            CHECK_ITEND( set, it );
+    it = set.find( 41 );            CHECK_ITEND( set, it );
 
-    CPPUNIT_ASSERT_MESSAGE( "find_bound", ((it = set.find_bound( -2 )) != set.end()) && (it->first == 0) );
-    CPPUNIT_ASSERT_MESSAGE( "find_bound", ((it = set.find_bound( -1 )) != set.end()) && (it->first == 0) );
-    CPPUNIT_ASSERT_MESSAGE( "find_bound", ((it = set.find_bound( 0 )) != set.end()) && (it->first == 0) );
-    CPPUNIT_ASSERT_MESSAGE( "find_bound", ((it = set.find_bound( 1 )) != set.end()) && (it->first == 0) );
-    CPPUNIT_ASSERT_MESSAGE( "find_bound", ((it = set.find_bound( 2 )) != set.end()) && (it->first == 5) );
-    CPPUNIT_ASSERT_MESSAGE( "find_bound", ((it = set.find_bound( 3 )) != set.end()) && (it->first == 5) );
-    CPPUNIT_ASSERT_MESSAGE( "find_bound", ((it = set.find_bound( 4 )) != set.end()) && (it->first == 5) );
-    CPPUNIT_ASSERT_MESSAGE( "find_bound", ((it = set.find_bound( 5 )) != set.end()) && (it->first == 5) );
-    CPPUNIT_ASSERT_MESSAGE( "find_bound", ((it = set.find_bound( 39 )) != set.end()) && (it->first == 30) );
-    CPPUNIT_ASSERT_MESSAGE( "find_bound", (it = set.find_bound( 40 )) == set.end() );
-    CPPUNIT_ASSERT_MESSAGE( "find_bound", (it = set.find_bound( 41 )) == set.end() );
+    it = set.find_bound( -2 );      CHECK_ITVALUE( set, it, 0 );
+    it = set.find_bound( -1 );      CHECK_ITVALUE( set, it, 0 );
+    it = set.find_bound( 0 );       CHECK_ITVALUE( set, it, 0 );
+    it = set.find_bound( 1 );       CHECK_ITVALUE( set, it, 0 );
+    it = set.find_bound( 2 );       CHECK_ITVALUE( set, it, 5 );
+    it = set.find_bound( 3 );       CHECK_ITVALUE( set, it, 5 );
+    it = set.find_bound( 4 );       CHECK_ITVALUE( set, it, 5 );
+    it = set.find_bound( 5 );       CHECK_ITVALUE( set, it, 5 );
+    it = set.find_bound( 39 );      CHECK_ITVALUE( set, it, 30 );
+    it = set.find_bound( 40 );      CHECK_ITEND( set, it );
+    it = set.find_bound( 41 );      CHECK_ITEND( set, it );
 
     // make intersection
 
-    static const Pair pairs_int[] = { {6,7},{15,27},{30,33} };
-    set_type set2 = set.make_intersection( interval( 6, 33 ) ); CALL_CHECK( set2, pairs_int );
+    set_type set2 = set.make_intersection( i(6,33) );
+    CHECK_CONTENTS( set2, "6,7,15,27,30,33" );
 
     // range c'tor, range insert, insert custom interval type
 
-    static const Pair pairs15a[] = { {7,7},{15,26} };
-    static const Pair init1[] = { {15,26},{7,7} };
-    set_type set3( init1, init1 + sizeof(init1)/sizeof(Pair) ); CALL_CHECK( set3, pairs15a );
+    struct Pair { short first; short second; };
+    
+    static const Pair init1[] = { {15,26}, {7,7} };
+    static const Pair init2 = {30,32};
+    static const int init3[] = {33,6,27};
 
-    static const Pair pairs15b[] = { {7,7},{15,26},{30,32} };
-    static const Pair init2 = {30,32};
-    set3.insert( init2 ); CALL_CHECK( set3, pairs15b );
+    set_type set3( init1, init1 + sizeof(init1)/sizeof(Pair) );
+    CHECK_CONTENTS( set3, "7,7,15,26" );
 
-    static const int init3[] = {33,6,27};
-    set3.insert( init3, init3 + sizeof(init3)/sizeof(int) ); CALL_CHECK( set3, pairs_int );
+    it = set3.insert( init2 );      CHECK_ITVALUE_CONTENTS( set3, it, 30, "7,7,15,26,30,32" );
+
+    set3.insert( init3, init3 + sizeof(init3)/sizeof(int) );
+    CHECK_CONTENTS( set3, "6,7,15,27,30,33" );
 
     // operator==
 
 
     // merge and overwrite
 
-    static const Pair pairs16[] = { {0,8},{15,27},{30,39} };
-    set.insert( interval( 1, 8 ) ); CALL_CHECK( set, pairs16 );
-
-    static const Pair pairs17[] = { {0,39} };
-    set.insert( interval( 9, 29 ) ); CALL_CHECK( set, pairs17 );
+    it = set.insert( i(1,8) );      CHECK_ITVALUE_CONTENTS( set, it, 0, "0,8,15,27,30,39" );
+    it = set.insert( i(9,29) );     CHECK_ITVALUE_CONTENTS( set, it, 0, "0,39" );
 
     // remove inside range
 
-    static const Pair pairs18[] = { {0,9},{11,19},{21,29},{31,39} };
-    set.erase( 10 ); set.erase( 20 ); set.erase( 30 ); CALL_CHECK( set, pairs18 );
-
-    static const Pair pairs19[] = { {0,9},{11,19},{24,29},{31,39} };
-    set.erase( interval( 21, 23 ) ); CALL_CHECK( set, pairs19 );
-
-    static const Pair pairs20[] = { {0,9},{11,19},{24,26},{31,39} };
-    set.erase( interval( 27, 29 ) ); CALL_CHECK( set, pairs20 );
-
-    static const Pair pairs21[] = { {0,9},{11,19},{31,39} };
-    set.erase( interval( 24, 26 ) ); CALL_CHECK( set, pairs21 );
+    it = set.erase( 10 );           CHECK_ITVALUE_CONTENTS( set, it, 11, "0,9,11,39" );
+    it = set.erase( 20 );           CHECK_ITVALUE_CONTENTS( set, it, 21, "0,9,11,19,21,39" );
+    it = set.erase( 30 );           CHECK_ITVALUE_CONTENTS( set, it, 31, "0,9,11,19,21,29,31,39" );
+    it = set.erase( i(21,23) );     CHECK_ITVALUE_CONTENTS( set, it, 24, "0,9,11,19,24,29,31,39" );
+    it = set.erase( i(27,29) );     CHECK_ITVALUE_CONTENTS( set, it, 31, "0,9,11,19,24,26,31,39" );
+    it = set.erase( i(24,26) );     CHECK_ITVALUE_CONTENTS( set, it, 31, "0,9,11,19,31,39" );
 
     // remove outside ranges
 
-    set.erase( -1 ); CALL_CHECK( set, pairs21 );
-    set.erase( 10 ); CALL_CHECK( set, pairs21 );
-    set.erase( interval( 20, 22 ) ); CALL_CHECK( set, pairs21 );
-    set.erase( interval( 29, 30 ) ); CALL_CHECK( set, pairs21 );
-    set.erase( interval( 20, 30 ) ); CALL_CHECK( set, pairs21 );
-    set.erase( interval( 40, 41 ) ); CALL_CHECK( set, pairs21 );
+    it = set.erase( -1 );           CHECK_ITVALUE_CONTENTS( set, it, 0, "0,9,11,19,31,39" );
+    it = set.erase( 10 );           CHECK_ITVALUE_CONTENTS( set, it, 11, "0,9,11,19,31,39" );
+    it = set.erase( i(20,22) );     CHECK_ITVALUE_CONTENTS( set, it, 31, "0,9,11,19,31,39" );
+    it = set.erase( i(29,30) );     CHECK_ITVALUE_CONTENTS( set, it, 31, "0,9,11,19,31,39" );
+    it = set.erase( i(20,30) );     CHECK_ITVALUE_CONTENTS( set, it, 31, "0,9,11,19,31,39" );
+    it = set.erase( i(40,41) );     CHECK_ITEND_CONTENTS( set, it, "0,9,11,19,31,39" );
 
     // remove in several ranges
 
-    static const Pair pairs22[] = { {0,6},{13,19},{31,39} };
-    set.erase( interval( 7, 12 ) ); CALL_CHECK( set, pairs22 );
-
-    static const Pair pairs23[] = { {0,5},{33,39} };
-    set.erase( interval( 6, 32 ) ); CALL_CHECK( set, pairs23 );
-
-    static const Pair pairs24[] = { {0,0} };
-    set.erase( interval( 1, 44 ) ); CALL_CHECK( set, pairs24 );
-
-    set.erase( interval( -1, 1 ) );
-    CPPUNIT_ASSERT_MESSAGE( "empty", set.empty() );
-
-#undef CALL_CHECK
-}
-
-void interval_set_test::check_set( const set_type& set, const Pair* pairs, size_t len, int line )
-{
-    const Pair* pairsend = pairs + len;
-    set_type::const_iterator it = set.begin(), itend = set.end();
-    int index = 0;
-    char buffer[ 256 ];
-    while( (it != itend) || (pairs != pairsend) )
-    {
-        bool itvalid = it != itend;
-        bool pairsvalid = pairs != pairsend;
-        if( itvalid && pairsvalid )
-            sprintf( buffer, "line: %d; failed: #%d; exp: (%d,%d); found: (%d,%d)", line, index, pairs->first, pairs->second, it->first, it->second );
-        else if( itvalid )
-            sprintf( buffer, "line: %d; failed: #%d; exp: [end]; found: (%d,%d)", line, index, it->first, it->second );
-        else
-            sprintf( buffer, "line: %d; failed: #%d; exp: (%d,%d); found: [end]", line, index, pairs->first, pairs->second );
-        CPPUNIT_ASSERT_MESSAGE( buffer, itvalid && pairsvalid && (it->first == pairs->first) && (it->second == pairs->second) );
-        if( itvalid ) ++it;
-        if( pairsvalid ) ++pairs;
-        ++index;
-    }
+    it = set.erase( i(7,12) );      CHECK_ITVALUE_CONTENTS( set, it, 13, "0,6,13,19,31,39" );
+    it = set.erase( i(6,32) );      CHECK_ITVALUE_CONTENTS( set, it, 33, "0,5,33,39" );
+    it = set.erase( i(1,44) );      CHECK_ITEND_CONTENTS( set, it, "0,0" );
+    it = set.erase( i(-1,1) );      CHECK_ITEND_CONTENTS( set, it, "" );
 }
 
 // -----------------------------------------------------------------------------