Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c++ fstream - creating own formatting flags

Tags:

c++

flags

fstream

i need to create new flags for the format of the output file. i have a class

class foo{
    bar* members;
    ofstream& operator<<(ofstream&);
    ifstream& operator>>(ifstream&);
};

and i want to use it like:

fstream os('filename.xml');
foo f;
os << xml << f;
os.close();

this will save an xml file.

fstream os('filename.json');
foo f;
os << json << f;
os.close();

and this an json file.

How can i do this?

like image 477
microo8 Avatar asked Mar 09 '12 06:03

microo8


1 Answers

You can easily create yor own manipulators, either hijacking an existing flag or using std::ios_base::xalloc to obtain new stream specific memory, e.g. (in the implementation file of Foo:

static int const manipFlagId = std::ios_base::xalloc();

enum
{
    fmt_xml,        //  Becomes the default.
    fmt_json
};

std::ostream&
xml( std::ostream& stream )
{
    stream.iword( manipFlagId ) = fmt_xml;
    return stream;
}

std::ostream&
json( std::ostream& stream )
{
    stream.iword( manipFlagId ) = fmt_json;
    return stream;
}

std::ostream&
operator<<( std::ostream& dest, Foo const& obj )
{
    switch ( dest.iword( manipFlagId ) ) {
    case fmt_xml:
        // ...
        break;
    case fmt_json:
        //  ...
        break;
    default:
        assert(0);  //  Or log error, or abort, or...
    }
    return dest;
}

Declare xml and json in your header, and the job is done.

(Having said this, I rather think that this is a bit of an abuse of manipulators. Formats like xml go beyond simple, local formatting, and are best handled by a separate class, which owns the ostream, and writes the entire stream, and not just individual objects.)

like image 177
James Kanze Avatar answered Oct 06 '22 21:10

James Kanze