/***************************************************************************
optstack.h - Header file for class optstack, for managing option values
-------------------
begin : Mon May 15 2006
copyright : (C) 2006 by Jan Rheinlaender
email : jrheinlaender@users.sourceforge.net
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef OPTSTACK_H
#define OPTSTACK_H
#include <string>
#include <vector>
#include <ginac/ginac.h>
using namespace GiNaC;
#include <stack>
#include "expression.h"
// *** rewrite in 1.2, now handles all options globally
/// Alignment types of equations
enum aligntype { // *** moved here from equation.h in 1.1
none, // No alignment
onlyleft, // Ampersand only before operator
onlyright,// Ampersand only after operator
both, // Ampersand on both sides of operator
left, // Ampersand on the left, used for addalign()
right // Ampersand on the right, used for addalign()
};
/// All the known options
enum option_name {
o_eqchain,
o_eqraw,
o_eqparse,
o_eqginac,
o_eqsplit,
o_eqsplittext,
o_vecautosize,
o_eqalign,
o_precision,
o_fixeddigits,
o_exponent,
o_lowsclimit,
o_highsclimit,
o_lang,
o_path,
o_units,
o_difftype, // *** added in 1.4.1
/* o_include_init, // *** added for iMath in 1.3.1
o_include_units,
o_include1,
o_include2,
o_include3,
o_masterdoc,*/
o_debug, // *** added in 1.4.3
o_comments, // *** added in 1.4.3
o_tan // *** added in 1.4.3
};
/// Possible types of options
enum option_type {
t_vec,
t_str,
t_bool,
t_dbl,
t_align,
t_uint,
t_int,
t_ex
};
// struct with union to store the different option values
typedef union option_value {
/// Vector of relationals
unitvec* vec;
/// String
std::string* str;
/// Alignment type
aligntype align;
/// Boolean
bool boolean;
/// Double
double dbl;
/// Unsigned integer
unsigned uinteger;
/// Integer
int integer;
/// Expression
ex* expr;
} option_value;
typedef struct option {
/// The option type, for integrity checking
option_type type;
/// The value
option_value value;
/// Create from different types
option() {};
option(unitvec v) { value.vec = new unitvec(v); type = t_vec; };
option(unitvec* v) { value.vec = v; type = t_vec; };
option(std::string v) { value.str = new std::string(v); type = t_str; };
option(std::string* v) { value.str = v; type = t_str; };
option(aligntype v) { value.align = v; type = t_align; };
option(bool v) { value.boolean = v; type = t_bool; };
option(double v) { value.dbl = v; type = t_dbl; };
option(unsigned v) { value.uinteger = v; type = t_uint; };
option(int v) { value.integer = v; type = t_int; };
option(ex v) { value.expr = new ex(v); type = t_ex; };
option(ex* v) { value.expr = v; type = t_ex; };
/// Compare two options
const bool operator==(const option& other) const;
const bool operator!=(const option& other) const;
/// Output the value (of the given type) onto a stream
void print(std::ostream &os) const;
} option;
/**
Stores the values of options, and enables multiple values to be saved and restored
This class implements multiple stacks which can be referenced by a key, the name
of the option.
@author Jan Rheinlaender
*/
class optstack{
public:
/// Create a new option stack
optstack();
/// Assign a new value to the option
void set(const option_name key, const option_value &value);
//void set(const option_name key, void *value);
/// Assign a boolean value to the option
void set(const option_name key, const bool value);
/// Assign a numeric value to the option (converting automatically to the correct type)
// void set(const option_name key, const ex &value);
/// Assign a string value to the option
void set(const option_name key, const std::string &value);
/// Return the value of the option
const option_value& get(const option_name key);
/// Register the type of an option and a default value
void registr(const option_name key, const option_type type, void *value);
void save(const option_name key);
void restore(const option_name key);
/// Remove all elements except the last (default) one
void clear(const option_name key);
/// Remove all elements from all options except the last (default) one
void clearall();
private:
/// Return the topmost element
const option_value& top(const option_name key);
/// Push a value
void push(const option_name key, const option_value &value);
/**
Remove the topmost element
@param key The option name
@exception invalid_argument(Stack is empty)
*/
void pop(const option_name key);
/// Duplicate the topmost element
void dup(const option_name key);
/// Return a string with the name of the option
const std::string name(const option_name key);
/// Map to store the stacks of options
std::map<const option_name, std::stack<option> > opts;
/// Map for string values of the option names (for debugging purposes)
std::map<const option_name, std::string> option_name_str;
public:
/// One class instance for all options from all classes
static optstack* options; // *** moved here in 1.3.1
static void init(); // *** added in 1.3.1
};
#endif