Boost logo

Boost :

From: John Torjo (john.lists_at_[hidden])
Date: 2004-04-21 12:22:52


Dear boosters,

When needing to dump a lot of data into a string, we usually use
boost::format. However, there have been lots of times when I needed a
simple and lightweight replacement.

I've used one for quite a while (see attachement).
Basic usage:
str_stream() << "str" << s << "int " << i; // automatic conversion to
string.
Example:
std::string msg = str_stream() << "There have been " << users << " users
logged on so far";

Also, attached an example.
Any interest in something like this in boost?

Best,
John <cid:part1.07010200.01010400_at_[hidden]>


//////////////////////////////////////////////////////////////////////
// example.cpp
#include "str_stream.hpp"
#include <iomanip>

std::basic_ostream< wchar_t> & width_4( std::basic_ostream< wchar_t> & out)
{
    out.width( 4);
    return out;
}

void print_c_like_str( const char * str) {
    std::cout << str << std::endl;
}

void test() {
    using namespace boost;
    // for wide strings.
    std::wstring str = wstr_stream() << std::oct << 8;
    str = wstr_stream() << std::setfill( L'0') << width_4 << 35 << std::endl;
    std::wcout << str;

    // for strings
    int users = 45;
    std::string s = str_stream() << "There have been " << users << " users logged on so far";
    std::cout << s << std::endl;

    int words = 78;
    s = str_stream( "We found ") << words << " words.";
    std::cout << s << std::endl;
    
    // convert it to C-like string
    print_c_like_str( (str_stream() << "testing " << 1 << 2 << 3).c_str() );
    std::cin.get();
}

int main() {
    test();
}

//////////////////////////////////////////////////////////////////////
// str_stream.h
#ifndef BOOST_STR_STREAM__HPP_JT_2003MAR04
#define BOOST_STR_STREAM__HPP_JT_2003MAR04

// Copyright John Torjo 2003-2004
// Use, modification, and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)

#include <string>
#include <sstream>
#include <iosfwd>

namespace boost {

namespace stream_detail {
    template< class char_type, class char_traits> struct as_c_str_res {
        typedef std::basic_string<char_type,char_traits> str_type;
        as_c_str_res( const str_type & str) { m_str = str; }
        operator const char_type*() const { return m_str.c_str(); }
    private:
        str_type m_str;
    };
}

// basic_str_stream - allow stream usage, and then conversion to string
template< class char_type, class char_traits = std::char_traits<char_type> > class basic_str_stream
{
    typedef std::basic_stringstream< char_type, char_traits> stringstream_type;
    typedef std::basic_string< char_type, char_traits> string_type;
    typedef stream_detail::as_c_str_res<char_type,char_traits> c_like_str_type;
public:
    // default construction
    basic_str_stream()
    {}

    // allow to_string like usage
    template< class type> basic_str_stream( const type & value) {
        *this << value;
    }

    stringstream_type & underlying_stream() const { return m_out; }

    // implicit conversion
    operator string_type() const { return m_out.str(); }

    // explicit conversion to string
    string_type str() const { return m_out.str(); }
    // explicit conversion to C-like string
    c_like_str_type c_str() const { return c_like_str_type( m_out.str() ); }
private:
    mutable stringstream_type m_out;

#ifndef NDEBUG
public:
    void recalculate_string() const
    { m_string = m_out.str(); }
private:
    mutable string_type m_string;
#endif
}; // class basic_str_stream

typedef basic_str_stream< char> str_stream;
typedef basic_str_stream< wchar_t> wstr_stream;

template< class char_type, class char_traits, class type>
inline const basic_str_stream< char_type, char_traits> & operator<< (
        const basic_str_stream< char_type, char_traits> & out,
        const type & value)
{
    out.underlying_stream() << value;
#ifndef NDEBUG
    out.recalculate_string();
#endif
    return out;
}

// allow function IO manipulators
template< class char_type, class char_traits>
inline const basic_str_stream< char_type, char_traits> & operator<< (
        const basic_str_stream< char_type, char_traits> & out,
        std::ios_base & (*func)( std::ios_base&) )
{
    func( out.underlying_stream());
    return out;
}

template< class char_type, class char_traits>
inline const basic_str_stream< char_type, char_traits> & operator<< (
        const basic_str_stream< char_type, char_traits> & out,
        std::basic_ios< char_type, char_traits> & (*func)( std::basic_ios< char_type, char_traits> &) )
{
    func( out.underlying_stream());
    return out;
}

template< class char_type, class char_traits>
inline const basic_str_stream< char_type, char_traits> & operator<< (
        const basic_str_stream< char_type, char_traits> & out,
        std::basic_ostream< char_type, char_traits> & (*func)( std::basic_ostream< char_type, char_traits> &) )
{
    func( out.underlying_stream());
    return out;
}

} // namespace boost

#endif
// End of file


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk