|
Boost : |
From: Thorsten Ottosen (nesotto_at_[hidden])
Date: 2003-10-27 08:33:54
"Pavol Droba" <droba_at_[hidden]> wrote in message
news:20031026155020.GG17011_at_lenin.felcer.sk...
> On Mon, Oct 27, 2003 at 02:07:47AM +1100, Thorsten Ottosen wrote:
> > You also called your functions firnd_first, not find_0th, and we have
> >
> > find_first( s, XX ) == find_nth( s, XX, 0 )
> >
> > which doesn't seem natural. It's like having an integer variable and
making
> > zero mean you have got one
> > of something.
> >
>
> What would then denote find_nth( s, XX, 0 )? Should it throw an exception?
a good idea. the argument could be an int and you could prevent [-max_int,0]
as input.
There's been some heated discussion once in a while, but I still don't get
that one would like to
use unsigned types.
> Why would you use
>
> for( unsigned int i=1; i<=n; i++ )
> {
> // do something with
> find_nth( s, XX, i );
> }
>
>
> and
>
> for( unsigned int i=0; i<n; i++ )
> {
> vector[i] = i;
> }
>
> ?
I don't see the similarity between the two examples. One is *searching* for
substrings another
is merely *accessing* a random access container at index i. It's not obvious
at all that these have anything in common;
So I merely asking for a good explanation :-)
>
> It is one of most basic conventions in C programing, that first element
has
> the index 0.
> Whatever are your reasons, but you want want to break something very
fundamental.
I don't know. It's like making the 1st of december into the 0th of december
AFAICT. I don't suppose date libraries do that.
> I'm against anything which would imply some explicit affinity to
std::string.
>
> I'm not against improvements to the iterator_range, but only with a
respect
> to an arbitrary container.
>
> We can call it substring, but only in terms of the string definition, I
have already
> mentioned. Everything else is a hack.
>
> So you most probably will not convince me to prefer std::basic_string in
the context
> of this library. It would break the basic properties of the design.
here'a a small hack. Maybe it's useful? Anyway, it shows how a substring
might be useful. The implementation could be better too.
If a "string" concept required a sequential data, the substring class could
probably be implemented in terms of char*.
#include <boost/string_algo.hpp>
#include <string>
#include <iosfwd>
#include <iterator>
#include <cstddef>
using namespace boost;
template< typename String >
class basic_substring
{
typedef typename string_algo::container_result_iterator<String>::type
iterator;
typedef typename string_algo::container_value_type<String>::type
value_type;
iterator begin_;
iterator end_;
public:
basic_substring( iterator b, iterator e )
: begin_( b ), end_( e )
{}
iterator begin() const
{
return begin_;
}
iterator end() const
{
return end_;
}
std::size_t size() const
{
return std::distance( begin_, end_ );
}
bool empty() const
{
return begin_ == end_;
}
typedef iterator (basic_substring::* safe_bool)();
operator safe_bool() const
{
return empty() ? 0 : &end;
}
friend inline std::ostream& operator<<( std::ostream& out,
basic_substring& s )
{
iterator i = s.begin_;
while( i != s.end_ )
{
out << *i;
++i;
}
return out;
}
};
template< typename String1, typename String2 >
std::basic_string< typename string_algo::container_value_type<String1>::type
>
operator+( const basic_substring<String1>& lhs, const
basic_substring<String2>& rhs )
{
std::basic_string< typename
string_algo::container_value_type<String1>::type > s( lhs.begin(),
lhs.end() );
s.insert( s.end(), rhs.begin(), rhs.end() );
return s;
}
template< typename String >
std::basic_string< typename string_algo::container_value_type<String>::type
>
operator+( const basic_substring<String>& lhs, const
std::basic_string<typename string_algo::container_value_type<String>::type>&
rhs )
{
std::basic_string< typename
string_algo::container_value_type<String>::type > s( lhs.begin(),
lhs.end() );
s.insert( s.end(), rhs.begin(), rhs.end() );
return s;
}
template< typename String >
std::basic_string< typename string_algo::container_value_type<String>::type
>
operator+( const std::basic_string<typename
string_algo::container_value_type<String>::type>& lhs, const
basic_substring<String>& rhs )
{
std::basic_string< typename
string_algo::container_value_type<String>::type > s( lhs.begin(),
lhs.end() );
s.insert( s.end(), rhs.begin(), rhs.end() );
return s;
}
typedef basic_substring< std::string > substring;
typedef basic_substring< std::wstring > wsubstring;
typedef basic_substring< const std::string > const_substring;
typedef basic_substring< const std::wstring > const_wsubstring;
template< typename String, typename SearchString >
basic_substring<String> find( String& s, const SearchString& bla )
{
return basic_substring<String>( string_algo::begin( s ),
string_algo::end( s ) );
}
template< typename SearchString >
basic_substring<std::string> find( char* s, const SearchString& bla )
{
return basic_substring<std::string>( string_algo::begin( s ),
string_algo::end( s ) );
}
#include <iostream>
int main()
{
using namespace std;
char array[] = "array hello";
string s = "hello world";
const string cs = "Hello World!";
substring match = find( s, "blabla" );
const_substring match2 = find( cs, "blafoo" );
substring match3 = find( array, "foobar" );
cout << match << match2 << match3;
cout << "fooo" + match + match2 + find( s, "goo" );
}
> And btw, you are right the in multi-threaded multi-locales environment,
> global locales are absolutely unusable ...
yeah, that must be the best argument.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk