#ifndef _COLUMN_H_
#define _COLUMN_H_
#include <iostream.h>
/** Clone a string.
This function allocates memory and clones the argument string
into that memory. For memory deallocation, *you* are responsible.
*/
char* newStr (const char* string);
class ColumnBase;
/** A column of data.
A column is an array of data, of type Double or String.
You can determinate the type of a column with the type()
function. The type is defined in the column´s constructor.
Data is accessed via the value(), setValue(), and operator[]
functions. Note that the operator[] does only make sence for
Double columns. (type() == Column::columnDouble.) But when
dealing with Double columns in numerical context, you should
definitively use the operator[], since it is a) faster and
b) doesn´t loose digits, since value() returns a string and
has to be re-converted to double.
For each column, a title() and a format() string is stored.
The function of the title is pretty obvious - it´s the name of
the column. What is less obvious about the title is that it´s
also used by the formula interpreter to look up a column.
The format string is used to set the precision of the worksheet
representation of numbers.
You can copy columns freely. They are implemented using
reference counting, so copying them is cheap.
Columns are implemented with a highly efficient auto-resizing
mechanism. Auto-resize is done in 1024-steps without copying,
that is, it´s comparatively fast. The current maximum size of
a column is 1048576 elements (8 MB + epsilon for doubles, 4 MB
+ epsilon + the actual text for strings).
@author Patrick Schemitz
*/
class Column
{
public:
/** Enumeration of columns types. An columnEmpty column does not contain
anything; columnDouble contains doubles, columnString strings.
(Pretty obvious.)
@see #type()
*/
enum ColumnType {
columnEmpty, columnDouble, columnString
};
public:
/** Column Constructor.
By default, this function generates an empty column, i.e. one
without any data. You can choose one of the types enumerated
in ColumnType.
@param col_type type of the new column
@see #type()
@see #ColumnType
*/
Column (ColumnType col_type = columnEmpty);
/** Copy constructor.
You may copy columns freely, since they are implemented using
reference counting. Copies are "flat" copies.
*/
Column (const Column&);
/** Column Destructor.
The column is destroyed, and if it was the last column using
the data, the data is also deleted; if, however, other columns
still refer to the same data, the data is *not* deleted.
*/
~Column ();
/** Assignment operator.
You may assign columns freely, since they are implemented using
reference counting. Copies are "flat" copies.
*/
Column& operator= (const Column&);
/** Identify type of a column.
The type returned is one of those defined in ColumnType,
namely the one from the constructor call the column was created
with - unless, of course, you used the assignment operator, in
which case the type is the same as of the assigned column.
@return type of the column
@see #ColumnType
*/
ColumnType type ();
/** Dimension of the column.
The dimension of an auto-resizing column is defined as
the index of the highest (possibly) *written* element.
That is, the highest index used in setValue() and operator[].
@return dimension of the column as defined above
@see #setValue()
@see #operator[]
*/
int dim ();
/** Value of a cell, as a string.
If the column holds strings, the requested string cell is
directly returned. ("" if unused/unset.) If the column holds doubles,
the number is sprintf´ed into a buffer using the format string
of the column, and this buffer is returned. ("-" if unused/unset.)
When doing math with double columns, you should definitively prefer
the operator[] due to both speed and precision. When printf´ing
a value o the buffer, digits get lost because the format string
might limit them to two digits. (Default; mileage may vary, but the
principle remains.)
This function does not enlarge the column, even if the index is
"out of range".
@param index index of the cell to be read out
@see #setFormat()
@see #setValue()
@see #operator[]
*/
const char* value (int index);
/** Set the value of a cell.
For string columns, a deep copy of the string is stored in the
appropriate cell; for double columns, the given string is converted
into a double using the C library routine, strtod(). If the
conversion fails, the content of the cell is set to NAN (printed as
"-").
If you set the last existing cell of a column to (char*)0, the
dimension of the column will be decremented by one.
When doing math with double columns, you should definitively prefer
the operator[], which is faster because it does not need to convert
the string to double.
If the cell was not allocated yet (i.e. the index was "out of range"),
the column is enlarged until it fits the index. This can cost quite
a large amount of memory, especially when you pass an idiotically
high index ("setValue(1000042,"42");").
If the index is higher than the current dimension of the column, the
dimension is set to index. Therefore, the dim() always returns the
index of the "highest" cell that is set to a value.
@param index index of the cell to be set
@param new_value new value of the specified cell
@see #dim()
@see #value()
@see #operator[]
*/
void setValue (int index, const char* new_value);
/** Reference to numerical value of a cell.
Use this whenever you´re doing math with double columns!
Use this only when you´re doing math with double columns!
For double columns, the operator[] provides a convenient and
fast method to get/set values. Plus, it does not loose digits
as value() might do.
If, however, you´re dealing with strings, this operator does not
make any sence. It will just return NAN, and if you change its
value, it will forget it immediately.
@param index index of the cell
@return reference to the specified cell
@see #dim()
@see #value()
@see #setValue()
*/
double& operator[] (int index);
/** Title of the column.
This returns the title of the column, as used in the
worksheet, and by the formula interpreter (when looking up
columns).
@return title of the column
@see #setTitle()
@see Formula
*/
const char* title ();
/** Change the title of the column.
This changes the title of the column, as used in the
worksheet, and by the formula interpreter (when looking up
columns).
@param new_title the new title of the column
@see #title()
*/
void setTitle (const char* new_title);
/** Format string of the column.
The format string is used by double columns to convert
doubles to strings in the value() function.
@return format string of the column
@see #value()
@see #setFormat()
*/
const char* format ();
/** Change the format string of the column.
The format string is used by double columns to convert
doubles to strings in the value() function.
@param new_format new format string of the column
@see #value()
@see #format()
*/
void setFormat (const char* new_format);
/** Dump a column to an ostream.
For debugging, you might want to dump a column to an ostream
(cout or cerr, most likely). To print the column "myColumn" to
the console, just go:
cout << myColumn << endl;
*/
friend ostream& operator<< (ostream&, Column&);
private:
/** Clear the column.
For internal use only.
Decrement the reference counter and eventually delete
the actual column data. Called by the destructor, and
on the old value of the l.h.s. at an assignment.
*/
void clear ();
private:
/** Type field of the column. */
ColumnType the_type;
/** Pointer to the actual data. */
ColumnBase* column;
/** Dummy; operator[] returns this for string columns. */
double dummy;
};
#endif
Documentation generated by patrick@nemesis on Tue Feb 10 23:05:12 MET 1998