Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r81884 - in trunk: boost/algorithm libs/algorithm/test
From: marshall_at_[hidden]
Date: 2012-12-12 21:17:49


Author: marshall
Date: 2012-12-12 21:17:49 EST (Wed, 12 Dec 2012)
New Revision: 81884
URL: http://svn.boost.org/trac/boost/changeset/81884

Log:
More tests for string_ref
Text files modified:
   trunk/boost/algorithm/string_ref.hpp | 56 +++++++++--------
   trunk/libs/algorithm/test/string_ref_test1.cpp | 38 +++++++++++-
   trunk/libs/algorithm/test/string_ref_test2.cpp | 122 ++++++++++++++++++++++++++++++++++++++-
   3 files changed, 181 insertions(+), 35 deletions(-)

Modified: trunk/boost/algorithm/string_ref.hpp
==============================================================================
--- trunk/boost/algorithm/string_ref.hpp (original)
+++ trunk/boost/algorithm/string_ref.hpp 2012-12-12 21:17:49 EST (Wed, 12 Dec 2012)
@@ -63,7 +63,7 @@
         typedef const_iterator iterator;
         typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
         typedef const_reverse_iterator reverse_iterator;
- typedef size_t size_type;
+ typedef std::size_t size_type;
         typedef ptrdiff_t difference_type;
         static BOOST_CONSTEXPR_OR_CONST size_type npos = size_type(-1);
         
@@ -162,18 +162,16 @@
             return cmp != 0 ? cmp : ( len_ == x.len_ ? 0 : len_ < x.len_ ? -1 : 1 );
             }
         
- bool starts_with(charT c) const { return !empty() && front() == c; }
+ bool starts_with(charT c) const { return !empty() && traits::eq ( c, front()); }
         bool starts_with(basic_string_ref x) const {
             return len_ >= x.len_ && traits::compare ( ptr_, x.ptr_, x.len_ ) == 0;
             }
         
- bool ends_with(charT c) const { return !empty() && back() == c; }
+ bool ends_with(charT c) const { return !empty() && traits::eq ( c, back()); }
         bool ends_with(basic_string_ref x) const {
             return len_ >= x.len_ && traits::compare ( ptr_ + len_ - x.len_, x.ptr_, x.len_ ) == 0;
             }
 
-
-// Have to use traits here
         size_type find(basic_string_ref s) const {
             const_iterator iter = std::search ( this->cbegin (), this->cend (),
                                                 s.cbegin (), s.cend (), traits::eq );
@@ -187,7 +185,7 @@
             }
                         
         size_type rfind(basic_string_ref s) const {
- const_iterator iter = std::search ( this->crbegin (), this->crend (),
+ const_reverse_iterator iter = std::search ( this->crbegin (), this->crend (),
                                                 s.crbegin (), s.crend (), traits::eq );
             return iter == this->crend () ? npos : reverse_distance ( this->crbegin (), iter );
             }
@@ -198,27 +196,24 @@
             return iter == this->crend () ? npos : reverse_distance ( this->crbegin (), iter );
             }
         
- size_type find_first_of(basic_string_ref s) const {
- const_iterator iter = std::find_first_of ( this->cbegin (), this->cend (),
- s.cbegin (), s.cend (), traits::eq );
- return iter = this->cend () ? npos : std::distance ( this->cbegin (), iter );
- }
-
         size_type find_first_of(charT c) const { return find (c); }
         size_type find_last_of (charT c) const { return rfind (c); }
-
+
+ size_type find_first_of(basic_string_ref s) const {
+ const_iterator iter = std::find_first_of
+ ( this->cbegin (), this->cend (), s.cbegin (), s.cend (), traits::eq );
+ return iter == this->cend () ? npos : std::distance ( this->cbegin (), iter );
+ }
         
         size_type find_last_of(basic_string_ref s) const {
- const_reverse_iterator iter = std::find_first_of ( this->crbegin (), this->crend (),
- s.crbegin (), s.crend (), traits::eq );
- return iter = this->cend () ? npos : reverse_distance ( this->crbegin (), iter);
+ const_reverse_iterator iter = std::find_first_of
+ ( this->crbegin (), this->crend (), s.cbegin (), s.cend (), traits::eq );
+ return iter == this->crend () ? npos : reverse_distance ( this->crbegin (), iter);
             }
         
         size_type find_first_not_of(basic_string_ref s) const {
- for ( const_reverse_iterator iter = this->cbegin (); iter != this->cend (); ++iter )
- if ( 0 == traits::find ( s->ptr_, s.len_, *iter ))
- return std::distance ( this->cbegin (), iter );
- return npos;
+ const_iterator iter = find_not_of ( this->cbegin (), this->cend (), s );
+ return iter == this->cend () ? npos : std::distance ( this->cbegin (), iter );
             }
         
         size_type find_first_not_of(charT c) const {
@@ -229,10 +224,8 @@
             }
         
         size_type find_last_not_of(basic_string_ref s) const {
- for ( const_reverse_iterator iter = this->crbegin (); iter != this->crend (); ++iter )
- if ( 0 == traits::find ( s.ptr_, s.len_, *iter ))
- return reverse_distance ( this->crbegin (), iter );
- return npos;
+ const_reverse_iterator iter = find_not_of ( this->crbegin (), this->crend (), s );
+ return iter == this->crend () ? npos : reverse_distance ( this->crbegin (), iter );
             }
         
         size_type find_last_not_of(charT c) const {
@@ -243,10 +236,21 @@
             }
 
     private:
- size_type reverse_distance ( reverse_iterator first, reverse_iterator last ) const {
- return len_ - 1 + std::distance ( first, last );
+ template <typename r_iter>
+ size_type reverse_distance ( r_iter first, r_iter last ) const {
+ return len_ - 1 - std::distance ( first, last );
             }
         
+ template <typename Iterator>
+ Iterator find_not_of ( Iterator first, Iterator last, basic_string_ref s ) const {
+ for ( ; first != last ; ++first )
+ if ( 0 == traits::find ( s.ptr_, s.len_, *first ))
+ return first;
+ return last;
+ }
+
+
+
         const charT *ptr_;
         std::size_t len_;
         };

Modified: trunk/libs/algorithm/test/string_ref_test1.cpp
==============================================================================
--- trunk/libs/algorithm/test/string_ref_test1.cpp (original)
+++ trunk/libs/algorithm/test/string_ref_test1.cpp 2012-12-12 21:17:49 EST (Wed, 12 Dec 2012)
@@ -22,10 +22,12 @@
 void interop ( const std::string &str, string_ref ref ) {
 // BOOST_CHECK ( str == ref );
     BOOST_CHECK ( str.size () == ref.size ());
- BOOST_CHECK ( std::equal ( str.begin (), str.end (), ref.begin ()));
+ BOOST_CHECK ( std::equal ( str.begin (), str.end (), ref.begin ()));
+ BOOST_CHECK ( std::equal ( str.rbegin (), str.rend (), ref.rbegin ()));
     }
 
-void substr ( const std::string &str ) {
+// make sure that substrings work just like strings
+void test_substr ( const std::string &str ) {
     const size_t sz = str.size ();
     string_ref ref ( str );
     
@@ -43,6 +45,33 @@
             interop ( str.substr ( i, j ), ref.substr ( i, j ));
     }
 
+// make sure that removing prefixes and suffixes work just like strings
+void test_remove ( const std::string &str ) {
+ const size_t sz = str.size ();
+ std::string work;
+ string_ref ref;
+
+ for ( size_t i = 1; i <= sz; ++i ) {
+ work = str;
+ ref = str;
+ while ( ref.size () >= i ) {
+ interop ( work, ref );
+ work.erase ( 0, i );
+ ref.remove_prefix (i);
+ }
+ }
+
+ for ( size_t i = 1; i < sz; ++ i ) {
+ work = str;
+ ref = str;
+ while ( ref.size () >= i ) {
+ interop ( work, ref );
+ work.erase ( work.size () - i, i );
+ ref.remove_suffix (i);
+ }
+ }
+ }
+
 const char *test_strings [] = {
     "",
     "1",
@@ -57,8 +86,9 @@
     
     while ( *p != NULL ) {
         interop ( *p, *p );
- substr ( *p );
-
+ test_substr ( *p );
+ test_remove ( *p );
+
         p++;
         }
 

Modified: trunk/libs/algorithm/test/string_ref_test2.cpp
==============================================================================
--- trunk/libs/algorithm/test/string_ref_test2.cpp (original)
+++ trunk/libs/algorithm/test/string_ref_test2.cpp 2012-12-12 21:17:49 EST (Wed, 12 Dec 2012)
@@ -8,6 +8,7 @@
 */
 
 #include <iostream>
+#include <cstring> // for std::strchr
 
 #include <boost/algorithm/string_ref.hpp>
 
@@ -16,6 +17,7 @@
 typedef boost::string_ref string_ref;
 
 void ends_with ( const char *arg ) {
+ const size_t sz = strlen ( arg );
     string_ref sr ( arg );
     string_ref sr2 ( arg );
     const char *p = arg;
@@ -36,10 +38,16 @@
         sr2.remove_prefix (1);
         }
 
- BOOST_CHECK ( sr.ends_with ( string_ref ()));
+ char ch = sz == 0 ? '\0' : arg [ sz - 1 ];
+ sr2 = arg;
+ if ( sz > 0 )
+ BOOST_CHECK ( sr2.ends_with ( ch ));
+ BOOST_CHECK ( !sr2.ends_with ( ++ch ));
+ BOOST_CHECK ( sr2.ends_with ( string_ref ()));
     }
     
 void starts_with ( const char *arg ) {
+ const size_t sz = strlen ( arg );
     string_ref sr ( arg );
     string_ref sr2 ( arg );
     const char *p = arg + std::strlen ( arg ) - 1;
@@ -54,7 +62,12 @@
         sr2.remove_suffix (1);
         }
 
- BOOST_CHECK ( sr.starts_with ( string_ref ()));
+ char ch = *arg;
+ sr2 = arg;
+ if ( sz > 0 )
+ BOOST_CHECK ( sr2.starts_with ( ch ));
+ BOOST_CHECK ( !sr2.starts_with ( ++ch ));
+ BOOST_CHECK ( sr2.starts_with ( string_ref ()));
     }
 
 void reverse ( const char *arg ) {
@@ -71,10 +84,56 @@
 
 
 void find ( const char *arg ) {
- string_ref sr1 ( arg );
- const char *p = arg;
-
+ string_ref sr1;
+ string_ref sr2;
+ const char *p;
+
+// Look for each character in the string(searching from the start)
+ p = arg;
+ sr1 = arg;
+ while ( *p ) {
+ string_ref::size_type pos = sr1.find(*p);
+ BOOST_CHECK ( pos != string_ref::npos && ( pos <= p - arg ));
+ ++p;
+ }
+
+// Look for each character in the string (searching from the end)
+ p = arg;
+ sr1 = arg;
+ while ( *p ) {
+ string_ref::size_type pos = sr1.rfind(*p);
+ BOOST_CHECK ( pos != string_ref::npos && pos < sr1.size () && ( pos >= p - arg ));
+ ++p;
+ }
+
+ sr1 = arg;
+ p = arg;
+// for all possible chars, see if we find them in the right place.
+// Note that strchr will/might do the _wrong_ thing if we search for NULL
+ for ( int ch = 1; ch < 256; ++ch ) {
+ string_ref::size_type pos = sr1.find(ch);
+ const char *strp = std::strchr ( arg, ch );
+ BOOST_CHECK (( strp == NULL ) == ( pos == string_ref::npos ));
+ if ( strp != NULL )
+ BOOST_CHECK (( strp - arg ) == pos );
+ }
+
+ sr1 = arg;
+ p = arg;
+// for all possible chars, see if we find them in the right place.
+// Note that strchr will/might do the _wrong_ thing if we search for NULL
+ for ( int ch = 1; ch < 256; ++ch ) {
+ string_ref::size_type pos = sr1.rfind(ch);
+ const char *strp = std::strrchr ( arg, ch );
+ BOOST_CHECK (( strp == NULL ) == ( pos == string_ref::npos ));
+ if ( strp != NULL )
+ BOOST_CHECK (( strp - arg ) == pos );
+ }
+
+
 // Find everything at the start
+ p = arg;
+ sr1 = arg;
     while ( !sr1.empty ()) {
         string_ref::size_type pos = sr1.find(*p);
         BOOST_CHECK ( pos == 0 );
@@ -112,12 +171,65 @@
         sr1.remove_suffix (1);
         --p;
         }
+
+// Basic sanity checking for "find_first_of / find_first_not_of"
+ sr1 = arg;
+ sr2 = arg;
+ while ( !sr1.empty() ) {
+ BOOST_CHECK ( sr1.find_first_of ( sr2 ) == 0 );
+ BOOST_CHECK ( sr1.find_first_not_of ( sr2 ) == string_ref::npos );
+ sr1.remove_prefix ( 1 );
+ }
+
+ p = arg;
+ sr1 = arg;
+ while ( *p ) {
+ string_ref::size_type pos1 = sr1.find_first_of(*p);
+ string_ref::size_type pos2 = sr1.find_first_not_of(*p);
+ BOOST_CHECK ( pos1 != string_ref::npos && pos1 < sr1.size () && pos1 <= ( p - arg ));
+ if ( pos2 != string_ref::npos ) {
+ for ( size_t i = 0 ; i < pos2; ++i )
+ BOOST_CHECK ( sr1[i] == *p );
+ BOOST_CHECK ( sr1 [ pos2 ] != *p );
+ }
+
+ BOOST_CHECK ( pos2 != pos1 );
+ ++p;
+ }
+
+// Basic sanity checking for "find_last_of / find_last_not_of"
+ sr1 = arg;
+ sr2 = arg;
+ while ( !sr1.empty() ) {
+ BOOST_CHECK ( sr1.find_last_of ( sr2 ) == ( sr1.size () - 1 ));
+ BOOST_CHECK ( sr1.find_last_not_of ( sr2 ) == string_ref::npos );
+ sr1.remove_suffix ( 1 );
+ }
+
+ p = arg;
+ sr1 = arg;
+ while ( *p ) {
+ string_ref::size_type pos1 = sr1.find_last_of(*p);
+ string_ref::size_type pos2 = sr1.find_last_not_of(*p);
+ BOOST_CHECK ( pos1 != string_ref::npos && pos1 < sr1.size () && pos1 >= ( p - arg ));
+ BOOST_CHECK ( pos2 == string_ref::npos || pos1 < sr1.size ());
+ if ( pos2 != string_ref::npos ) {
+ for ( size_t i = sr1.size () -1 ; i > pos2; --i )
+ BOOST_CHECK ( sr1[i] == *p );
+ BOOST_CHECK ( sr1 [ pos2 ] != *p );
+ }
+
+ BOOST_CHECK ( pos2 != pos1 );
+ ++p;
+ }
+
     }
 
 const char *test_strings [] = {
     "",
     "0",
     "abc",
+ "AAA", // all the same
     "adsfadadiaef;alkdg;aljt;j agl;sjrl;tjs;lga;lretj;srg[w349u5209dsfadfasdfasdfadsf",
     "abc\0asdfadsfasf",
     NULL


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk