By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
445,918 Members | 2,240 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 445,918 IT Pros & Developers. It's quick & easy.

solution for max_length_string (?)

P: n/a
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< charT , traitsT >&
operator<<( std::basic_ostream< charT , traitsT >& os, max_lenght_string< N
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;
}
}


Jul 22 '05 #1
Share this Question
Share on Google+
9 Replies


P: n/a
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< N <= M , max_lenght_string< N > , null_type
::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
Jul 22 '05 #2

P: n/a
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< N <= M, max_lenght_string< N >, null_type
::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

Jul 22 '05 #3

P: n/a
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< N <= M, max_lenght_string< M >, null_type
::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
Jul 22 '05 #4

P: n/a
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< N <= M, max_lenght_string< M >, null_type
::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

Jul 22 '05 #5

P: n/a
Oliver Kowalke wrote:
....
// max_lenght_string< 1 > a7("abc"); // run-time error


I think you can make this a compile time error.

Jul 22 '05 #6

P: n/a
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
{
typedef typename if_then_else< N <= M, max_lenght_string< M >, null_type
::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

Jul 22 '05 #7

P: n/a
Gianni Mariani wrote:
Oliver Kowalke wrote:
...
// max_lenght_string< 1 > a7("abc"); // run-time error


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?

Jul 22 '05 #8

P: n/a
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
{
typedef typename if_then_else< N <= M, max_lenght_string< M >, null_type
::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

Jul 22 '05 #9

P: n/a
Oliver Kowalke wrote:
Gianni Mariani wrote:

Oliver Kowalke wrote:
...
// max_lenght_string< 1 > a7("abc"); // run-time error


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?


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.

Jul 22 '05 #10

This discussion thread is closed

Replies have been disabled for this discussion.