solution for max_length_string (?)

O

Oliver Kowalke

Hi,

i need a string which can be used with the stl and should have a fixed max.
length. strings with different max_lenght should be different types.
assignment/copy construction from a string with equal or less max_lenght
should be possible and vice versa not.
is my suggestion a good solution? any improvements? or does a better
solution exist?
thx,
Oliver

#include <iosfwd>
#include <string>
#include <stdexcept>

struct null_type;

template< bool B , typename T , typename E >
struct if_then_else;

template< typename T , typename E >
struct if_then_else< true , T , E>
{
typedef T result_type;
};

template< typename T , typename E >
struct if_then_else< false , T , E>
{
typedef E result_type;
};

template< int N >
class max_lenght_string
{
private:
std::string str_;

template< int M >
friend class max_lenght_string;

template< typename charT , typename traitsT >
friend std::basic_ostream< charT , traitsT >&
operator<<( std::basic_ostream< charT , traitsT >& os, max_lenght_string<
N > const& str);

template< int M >
static
std::string const&
access( typename if_then_else< N <= M , max_lenght_string< N > ,
null_type >::result_type const& str)
{
return str.str_;
}

static
std::string const&
check( std::string const& str)
{
if( str.size() > N)
throw std::runtime_error("string ist too large");
return str;
}

public:
max_lenght_string( std::string const& str)
:
str_( max_lenght_string::check( str) )
{}
max_lenght_string( char const* c)
:
str_( max_lenght_string::check( std::string( c) ) )
{}

max_lenght_string( max_lenght_string const& str)
:
str_( str.str_ )
{}

template< int M >
max_lenght_string( max_lenght_string< M > const& str)
:
str_( max_lenght_string< M >::access< N >( str) )
{}

max_lenght_string const&
operator=( max_lenght_string const& rhs)
{
max_lenght_string tmp( rhs);
str_.swap( tmp.str_);
return *this;
}

template< int M >
max_lenght_string const&
operator=( max_lenght_string< M > const& rhs)
{
max_lenght_string< N > tmp( rhs);
str_.swap( tmp.str_);
return *this;
}

// c_str(), iterators, begin(), end(), ... left open
};

template< typename charT , typename traitsT , int N >
std::basic_ostream said:
const& str)
{
if( ! os) return os;
os << str.str_;
return os;
}

int main(int argc, char *argv[])
{
try
{
max_lenght_string< 1 > a1("a");
max_lenght_string< 1 > a2("b");
max_lenght_string< 2 > a3("ab");
max_lenght_string< 2 > a4( a2); // ok
max_lenght_string< 2 > a5( a4); // ok
// max_lenght_string< 1 > a6( a3); // compile-time error
// max_lenght_string< 1 > a7("abc"); // run-time error

a1 = a2; // ok
a3 = a1; // ok
// a2 = a3; // compile-time error

std::cout << "a1 = " << a1 << std::endl;
std::cout << "a2 = " << a2 << std::endl;
std::cout << "a3 = " << a3 << std::endl;
std::cout << "a4 = " << a4 << std::endl;
std::cout << "a5 = " << a5 << std::endl;

return 0;
}
catch( std::exception const& ex)
{
std::cout << "exception : " << ex.what() << std::endl;
return 1;
}
catch(...)
{
std::cout << "unhandled exception" << std::endl;
return 1;
}
}
 
O

Oliver Kowalke

instead of:

....
private:

template< int M >
friend class max_lenght_string;

template< int M >
static
std::string const&
access( typename if_then_else< N <= M , max_lenght_string< N > ,
null_type >::result_type const& str)
{
return str.str_;
}
....


i tried:

....
private:

template< int M >
struct X
{
typedef typename if_then_else said:
::result_type >::result_type;
};

template< int M >
friend typename A< N >::X< M >::result_type;
// A< M > should be friend if N <= M; if N > M null_type will be friend

public:
...
template< int M >
A( A< M > const& a)
:
str_( a.str_) // works only if A< N > is friend of A< M >
{}
....


but ms vc 7.1 will not compile for the friend declaration.
any suggestions?
thx,
Oliver
 
O

Oliver Kowalke

instead of:

....
private:

template< int M >
friend class max_lenght_string;

template< int M >
static
std::string const&
access( typename if_then_else< N <= M , max_lenght_string< N > ,
null_type >::result_type const& str)
{
return str.str_;
}
....


i tried:

....
private:

template< int M >
struct X
{
::result_type result_type;
};

template< int M >
friend typename A< N >::X< M >::result_type;
// A< M > should be friend if N <= M; if N > M null_type will be friend

public:
...
template< int M >
A( A< M > const& a)
:
str_( a.str_) // works only if A< N > is friend of A< M >
{}
....


but ms vc 7.1 will not compile for the friend declaration.
any suggestions?
thx,
Oliver
 
O

Oliver Kowalke

instead of:

....
private:

template< int M >
friend class max_lenght_string;

template< int M >
static
std::string const&
access( typename if_then_else< N <= M , max_lenght_string< N > ,
null_type >::result_type const& str)
{
return str.str_;
}
....


i tried:

....
private:

template< int M >
struct X
{
::result_type result_type;
};

template< int M >
friend typename A< N >::X< M >::result_type;
// A< M > should be friend if N <= M; if N > M null_type will be friend

public:
...
template< int M >
A( A< M > const& a)
:
str_( a.str_) // works only if A< N > is friend of A< M >
{}
....


but ms vc 7.1 will not compile for the friend declaration.
any suggestions?
thx,
Oliver
 
O

Oliver Kowalke

instead of:

....
private:

template< int M >
friend class max_lenght_string;

template< int M >
static
std::string const&
access( typename if_then_else< N <= M , max_lenght_string< N > ,
null_type >::result_type const& str)
{
return str.str_;
}
....


i tried:

....
private:

template< int M >
struct X
{
::result_type result_type;
};

template< int M >
friend typename max_lenght_string< N >::X< M >::result_type;
// friend typename max_lenght_string::X< M >::result_type;
// max_lenght_string< M > should be friend if N <= M
// if N > M null_type will be friend

public:
...
template< int M >
max_lenght_string( max_lenght_string< M > const& a)
:
str_( a.str_) // works only if max_lenght_string< N > is friend
// of max_lenght_string< M >
{}
....


but ms vc 7.1 will not compile for the friend declaration!
any suggestions?
thx,
Oliver
 
O

Oliver Kowalke

instead of:

....
private:

template< int M >
friend class max_lenght_string;

template< int M >
static
std::string const&
access( typename if_then_else< N <= M , max_lenght_string< N > ,
null_type >::result_type const& str)
{
return str.str_;
}
....


i tried (no static access; only friend template declaration):

....
private:

template< int M >
struct X
{
::result_type result_type;
};

template< int M >
friend typename max_lenght_string< N >::X< M >::result_type;
// friend typename max_lenght_string::X< M >::result_type;
// max_lenght_string< M > should be friend if N <= M
// if N > M null_type will be friend

public:
...
template< int M >
max_lenght_string( max_lenght_string< M > const& a)
:
str_( a.str_) // works only if max_lenght_string< N > is friend
// of max_lenght_string< M >
{}
....


but ms vc 7.1 will not compile for the friend declaration!
any suggestions?
thx,
Oliver
 
O

Oliver Kowalke

Gianni said:
Oliver Kowalke wrote:
...

I think you can make this a compile time error.

i'm not sure but i think on compile-time i didn't know what size the string
will have.
maybe you are so kind to tell me your solution?
 
O

Oliver Kowalke

instead of:

....
private:

template< int M >
friend class max_lenght_string;

template< int M >
static
std::string const&
access( typename if_then_else< N <= M , max_lenght_string< N > ,
null_type >::result_type const& str)
{
return str.str_;
}
....


i tried (no static access; only friend template declaration):

....
private:

template< int M >
struct X
{
::result_type result_type;
};

template< int M >
friend typename max_lenght_string< N >::X< M >::result_type;
// friend typename max_lenght_string::X< M >::result_type;
// max_lenght_string< M > should be friend if N <= M
// if N > M null_type will be friend

public:
...
template< int M >
max_lenght_string( max_lenght_string< M > const& a)
:
str_( a.str_) // works only if max_lenght_string< N > is friend
// of max_lenght_string< M >
{}
....


but ms vc 7.1 will not compile for the friend declaration!
any suggestions?
thx,
Oliver
 
G

Gianni Mariani

Oliver said:
Gianni Mariani wrote:




i'm not sure but i think on compile-time i didn't know what size the string
will have.
maybe you are so kind to tell me your solution?

You can get access to the size using a template but you need to change
the max_lenght_string( const char * c) constructor to be a template
also, otherwise it won't happen.


template <typename T>
max_lenght_string( T * c)
: str_( max_lenght_string::check( std::string( c) ) )
{}

template <unsigned SL>
max_lenght_string( char const (& str)[SL] )
: str_( max_lenght_string::str_access<SL>( str ) )
{}


BTW - I had a hard time compiling your example on gcc.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,148
Messages
2,570,838
Members
47,385
Latest member
Joneswilliam01

Latest Threads

Top