solution for max_length_string (?)

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Oliver Kowalke

    solution for max_length_string (?)

    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_stri ng
    {
    private:
    std::string str_;

    template< int M >
    friend class max_lenght_stri ng;

    template< typename charT , typename traitsT >
    friend std::basic_ostr eam< charT , traitsT >&
    operator<<( std::basic_ostr eam< charT , traitsT >& os, max_lenght_stri ng<
    N > const& str);

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

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

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

    max_lenght_stri ng( max_lenght_stri ng const& str)
    :
    str_( str.str_ )
    {}

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

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

    template< int M >
    max_lenght_stri ng const&
    operator=( max_lenght_stri ng< M > const& rhs)
    {
    max_lenght_stri ng< 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_ostr eam< charT , traitsT >&
    operator<<( std::basic_ostr eam< charT , traitsT >& os, max_lenght_stri ng< N[color=blue]
    > const& str)[/color]
    {
    if( ! os) return os;
    os << str.str_;
    return os;
    }

    int main(int argc, char *argv[])
    {
    try
    {
    max_lenght_stri ng< 1 > a1("a");
    max_lenght_stri ng< 1 > a2("b");
    max_lenght_stri ng< 2 > a3("ab");
    max_lenght_stri ng< 2 > a4( a2); // ok
    max_lenght_stri ng< 2 > a5( a4); // ok
    // max_lenght_stri ng< 1 > a6( a3); // compile-time error
    // max_lenght_stri ng< 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;
    }
    }




  • Oliver Kowalke

    #2
    Re: solution for max_length_stri ng (?)

    instead of:

    ....
    private:

    template< int M >
    friend class max_lenght_stri ng;

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


    i tried:

    ....
    private:

    template< int M >
    struct X
    {
    typedef typename if_then_else< N <= M , max_lenght_stri ng< N > , null_type[color=blue]
    >::result_typ e >::result_typ e;[/color]
    };

    template< int M >
    friend typename A< N >::X< M >::result_typ e;
    // 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

    Comment

    • Oliver Kowalke

      #3
      Re: solution for max_length_stri ng (?)

      instead of:

      ....
      private:

      template< int M >
      friend class max_lenght_stri ng;

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


      i tried:

      ....
      private:

      template< int M >
      struct X
      {
      typedef typename if_then_else< N <= M, max_lenght_stri ng< N >, null_type[color=blue]
      >::result_typ e result_type;[/color]
      };

      template< int M >
      friend typename A< N >::X< M >::result_typ e;
      // 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

      Comment

      • Oliver Kowalke

        #4
        Re: solution for max_length_stri ng (?)

        instead of:

        ....
        private:

        template< int M >
        friend class max_lenght_stri ng;

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


        i tried:

        ....
        private:

        template< int M >
        struct X
        {
        typedef typename if_then_else< N <= M, max_lenght_stri ng< M >, null_type[color=blue]
        >::result_typ e result_type;[/color]
        };

        template< int M >
        friend typename A< N >::X< M >::result_typ e;
        // 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

        Comment

        • Oliver Kowalke

          #5
          Re: solution for max_length_stri ng (?)

          instead of:

          ....
          private:

          template< int M >
          friend class max_lenght_stri ng;

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


          i tried:

          ....
          private:

          template< int M >
          struct X
          {
          typedef typename if_then_else< N <= M, max_lenght_stri ng< M >, null_type[color=blue]
          >::result_typ e result_type;[/color]
          };

          template< int M >
          friend typename max_lenght_stri ng< N >::X< M >::result_typ e;
          // friend typename max_lenght_stri ng::X< M >::result_typ e;
          // max_lenght_stri ng< M > should be friend if N <= M
          // if N > M null_type will be friend

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


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

          Comment

          • Gianni Mariani

            #6
            Re: solution for max_length_stri ng (?)

            Oliver Kowalke wrote:
            ....[color=blue]
            > // max_lenght_stri ng< 1 > a7("abc"); // run-time error[/color]

            I think you can make this a compile time error.

            Comment

            • Oliver Kowalke

              #7
              Re: solution for max_length_stri ng (?)

              instead of:

              ....
              private:

              template< int M >
              friend class max_lenght_stri ng;

              template< int M >
              static
              std::string const&
              access( typename if_then_else< N <= M , max_lenght_stri ng< N > ,
              null_type >::result_typ e 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_stri ng< M >, null_type[color=blue]
              >::result_typ e result_type;[/color]
              };

              template< int M >
              friend typename max_lenght_stri ng< N >::X< M >::result_typ e;
              // friend typename max_lenght_stri ng::X< M >::result_typ e;
              // max_lenght_stri ng< M > should be friend if N <= M
              // if N > M null_type will be friend

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


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

              Comment

              • Oliver Kowalke

                #8
                Re: solution for max_length_stri ng (?)

                Gianni Mariani wrote:
                [color=blue]
                > Oliver Kowalke wrote:
                > ...[color=green]
                >> // max_lenght_stri ng< 1 > a7("abc"); // run-time error[/color]
                >
                > I think you can make this a compile time error.[/color]

                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?

                Comment

                • Oliver Kowalke

                  #9
                  Re: solution for max_length_stri ng (?)

                  instead of:

                  ....
                  private:

                  template< int M >
                  friend class max_lenght_stri ng;

                  template< int M >
                  static
                  std::string const&
                  access( typename if_then_else< N <= M , max_lenght_stri ng< N > ,
                  null_type >::result_typ e 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_stri ng< M >, null_type[color=blue]
                  >::result_typ e result_type;[/color]
                  };

                  template< int M >
                  friend typename max_lenght_stri ng< N >::X< M >::result_typ e;
                  // friend typename max_lenght_stri ng::X< M >::result_typ e;
                  // max_lenght_stri ng< M > should be friend if N <= M
                  // if N > M null_type will be friend

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


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

                  Comment

                  • Gianni Mariani

                    #10
                    Re: solution for max_length_stri ng (?)

                    Oliver Kowalke wrote:[color=blue]
                    > Gianni Mariani wrote:
                    >
                    >[color=green]
                    >>Oliver Kowalke wrote:
                    >>...
                    >>[color=darkred]
                    >>> // max_lenght_stri ng< 1 > a7("abc"); // run-time error[/color]
                    >>
                    >>I think you can make this a compile time error.[/color]
                    >
                    >
                    > 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?
                    >[/color]

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


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

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


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

                    Comment

                    Working...