Chapter 67
IO Streams

Andreas Fabri, Geert-Jan Giezeman, and Lutz Kettner

Table of Contents

67.1 Output Operator
67.2 Input Operator
67.3 IO for non-CGAL types
   67.3.1   Using Output Formatting
   67.3.2   Customizing Output Formatting
67.4 Colors
67.5 Stream Support

All classes in the CGAL kernel provide input and output operators for IO streams. Classes external to CGAL are also supported, by means of oformat (Section 67.3). The basic task of such an operator is to produce a representation of an object that can be written as a sequence of characters on devices as a console, a file, or a pipe. In CGAL we distinguish between a raw ascii, a raw binary and a pretty printing format.

enum Mode { ASCII = 0, BINARY, PRETTY};

In ASCII mode, objects are written as a set of numbers, e.g. the coordinates of a point or the coefficients of a line, in a machine independent format. In BINARY mode, data are written in a binary format, e.g. a double is represented as a sequence of four byte. The format depends on the machine. The mode PRETTY serves mainly for debugging as the type of the geometric object is written, as well as the data defining the object. For example for a point at the origin with Cartesian double coordinates, the output would be PointC2(0.0, 0.0). At the moment CGAL does not provide input operations for pretty printed data. By default a stream is in ASCII mode.

CGAL provides the following functions to modify the mode of an IO stream.

IO::Mode set_mode ( std::ios& s, IO::Mode m)

IO::Mode set_ascii_mode ( std::ios& s)
IO::Mode set_binary_mode ( std::ios& s)
IO::Mode set_pretty_mode ( std::ios& s)

The following functions allow to test whether a stream is in a certain mode.

IO::Mode get_mode ( std::ios& s)

bool is_ascii ( std::ios& s)
bool is_binary ( std::ios& s)
bool is_pretty ( std::ios& s)

67.1   Output Operator

CGAL defines output operators for classes that are derived from the class ostream. This allows to write to ostreams as cout or cerr, as well as to strstreams and fstreams. The output operator is defined for all classes in the CGAL kernel and for the class Color as well. Let os be an output stream.

ostream& ostream& os << Class c Inserts object c in the stream os. Returns os.

Example


#include <CGAL/basic.h>
#include <iostream>
#include <fstream>

#include <CGAL/Cartesian.h>
#include <CGAL/Segment_2.h>

typedef CGAL::Point_2< CGAL::Cartesian<double> >     Point;
typedef CGAL::Segment_2< CGAL::Cartesian<double> >   Segment;

int main()
{
    Point p(0,1), q(2,2);
    Segment s(p,q);

    CGAL::set_pretty_mode(std::cout);
    std::cout << p << std::endl << q  << std::endl;

    std::ofstream f("data.txt");
    CGAL::set_binary_mode(f);
    f << s << p ;

    return 1;
}

67.2   Input Operator

CGAL defines input operators for classes that are derived from the class istream. This allows to read from istreams as cin, as well as from strstreams and fstreams. The input operator is defined for all classes in the CGAL kernel. Let is be an input stream.

istream& istream& is >> Class c Extracts object c from the stream is. Returns is.

Example


#include <CGAL/basic.h>
#include <iostream>
#include <fstream>

#include <CGAL/Cartesian.h>
#include <CGAL/Segment_2.h>

typedef CGAL::Point_2< CGAL::Cartesian<double> >     Point;
typedef CGAL::Segment_2< CGAL::Cartesian<double> >   Segment;

int
main()
{
    Point p, q;
    Segment s;

    CGAL::set_ascii_mode(std::cin);
    std::cin >> p >> q;

    std::ifstream f("data.txt");
    CGAL::set_binary_mode(f);
    f >> s >> p;

    return 1;
}

67.3   IO for non-CGAL types

67.3.1   Using Output Formatting

To ensure that non-CGAL types are formatted correctly (i.e., respecting IO::Mode), oformat can be used. For types with a Output_rep specialization, the respective output routine of Output_rep will be called by oformat. Otherwise, the stream output operator will be called.

Example

std::cout << CGAL::oformat( myobject );

Optional, you can provide a second template parameter F as a formatting tag:

Example

std::cout << CGAL::oformat( myobject, My_formatting_tag() );

For a list of formatting tags supported by the type T, please refer to the documentation of the respective type.

67.3.2   Customizing Output Formatting

In some situations, you want to control the output formatting for a type T. For external types (third party libraries etc.), there might be problems if their stream output operator does not respect IO::Mode. The purpose of Output_rep is to provide a way to control output formatting that works independently of the object's stream output operator.

Instead of putting T directly into an output stream, T is wrapped into an output representation Output_rep. For convenience, a function oformat exists which constructs an instance of Output_rep.

If you do not specialize Output_rep for T, T's stream output operator is called from within Output_rep, by default. If you want another behaviour for your type T, you have to provide a specialization for that type. Furthermore, you can provide specializations with a second template parameter (a formatting tag). The second template parameter defaults to Null_tag and means default behaviour.

For example, specializing Output_rep for CORE::BigRat (without a formatting tag parameter) could look like this:

Example

template <class F>
class Output_rep< ::CORE::BigRat, F> {
    const ::CORE::BigRat& t;
public:
    Output_rep( const ::CORE::BigRat& tt) : t(tt) {}

    std::ostream& operator()( std::ostream& out) const {
        switch (get_mode(out)) {
        case IO::PRETTY:{
            if(CGAL_CORE_DENOMINATOR(t) == ::CORE::BigRat(1))
                return out <<CGAL_CORE_NUMERATOR(t);
            else
                return out << CGAL_CORE_NUMERATOR(t)
                           << "/"
                           << CGAL_CORE_DENOMINATOR(t);
            break;
        }

        default:
            return out << CGAL_CORE_NUMERATOR(t)
                       << "/"
                       << CGAL_CORE_DENOMINATOR(t);
        }
    }
};

67.4   Colors

An object of the class CGAL::Color is a color available for drawing operations in many CGAL output streams.

Each color is defined by a triple of integers (r,g,b) with 0 r,g,b 255, the so-called rgb-value of the color. There are a 11 predefined Color constants available: BLACK, WHITE, GRAY, RED, GREEN, DEEPBLUE, BLUE, PURPLE, VIOLET, ORANGE, and YELLOW.

67.5   Stream Support

Three classes are provided by CGAL as adaptors to input and output stream iterators. The class Istream_iterator is an input iterator adaptor and is particularly useful for classes that are similar but not compatible to std::istream. Similarly, the class Ostream_iterator is an output iterator adaptor. The class Verbose_ostream can be used as an output stream. The stream output operator << is defined for any type. The class stores in an internal state a stream and whether the output is active or not. If the state is active, the stream output operator << uses the internal stream to output its argument. If the state is inactive, nothing happens.