1/*
2 Qalculate
3
4 Copyright (C) 2003-2007 Niklas Knutsson (nq@altern.org)
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10*/
11
12#ifndef UNIT_H
13#define UNIT_H
14
15/** @file */
16
17/// Type of unit
18typedef enum {
19 /// class Unit
20 SUBTYPE_BASE_UNIT,
21 /// class AliasUnit
22 SUBTYPE_ALIAS_UNIT,
23 /// class CompositeUnit
24 SUBTYPE_COMPOSITE_UNIT
25} UnitSubtype;
26
27#include <libqalculate/ExpressionItem.h>
28#include <libqalculate/includes.h>
29
30/// A unit for measurement.
31/**
32* The Unit class both represents a base unit and is the base class for other unit types.
33* Base units are units defined as basis for other units. Meters and seconds are typical base units.
34*
35* For base units, a name is all that is needed.
36* Base units do however normally have three different names defined for use in expressions - abbreviation (ex. "m"), singular ("meter") and plural ("meters").
37*/
38class Unit : public ExpressionItem {
39
40 protected:
41
42 string ssystem;
43 bool b_si;
44
45 public:
46
47 Unit(string cat_, string name_, string plural_ = "", string singular_ = "", string title_ = "", bool is_local = true, bool is_builtin = false, bool is_active = true);
48 Unit();
49 Unit(const Unit *unit);
50 virtual ~Unit();
51
52 virtual ExpressionItem *copy() const;
53 virtual void set(const ExpressionItem *item);
54
55 /** Returns if the unit is part of the SI standard.
56 *
57 * @returns true if the unit is part of the SI standard.
58 */
59 bool isSIUnit() const;
60 /** State that the unit is part of the SI standard.
61 * Sets system to "SI".
62 */
63 void setAsSIUnit();
64 /** Sets which system/standard ("SI", "SGC", etc.) the unit is part of.
65 * Setting system to "SI" (case-insensitive), is equivalent to setAsSIUnit().
66 */
67 void setSystem(string s_system);
68 /** Returns the system/standard that the unit is part of.
69 *
70 * @returns System string.
71 */
72 const string &system() const;
73 /** Returns if the unit is a currency (Euro is base unit).
74 *
75 * @returns true if the unit is a currency.
76 */
77 bool isCurrency() const;
78 /** Returns a display string representing the unit in an expression.
79 *
80 * Equivalent to preferredName() for Unit and AliasUnit, but closer to MathStructure::print() for CompositeUnit (prints out base expression).
81 */
82 virtual string print(bool plural_, bool short_, bool use_unicode = false, bool (*can_display_unicode_string_function) (const char*, void*) = NULL, void *can_display_unicode_string_arg = NULL) const;
83 virtual const string &plural(bool return_singular_if_no_plural = true, bool use_unicode = false, bool (*can_display_unicode_string_function) (const char*, void*) = NULL, void *can_display_unicode_string_arg = NULL) const;
84 virtual const string &singular(bool return_abbreviation_if_no_singular = true, bool use_unicode = false, bool (*can_display_unicode_string_function) (const char*, void*) = NULL, void *can_display_unicode_string_arg = NULL) const;
85 virtual const string &abbreviation(bool return_singular_if_no_abbreviation = true, bool use_unicode = false, bool (*can_display_unicode_string_function) (const char*, void*) = NULL, void *can_display_unicode_string_arg = NULL) const;
86 virtual bool isUsedByOtherUnits() const;
87 virtual Unit* baseUnit() const;
88 virtual MathStructure &convertToBaseUnit(MathStructure &mvalue, MathStructure &mexp) const;
89 virtual MathStructure &convertFromBaseUnit(MathStructure &mvalue, MathStructure &mexp) const;
90 virtual MathStructure &convertToBaseUnit(MathStructure &mvalue) const;
91 virtual MathStructure &convertFromBaseUnit(MathStructure &mvalue) const;
92 virtual MathStructure convertToBaseUnit() const;
93 virtual MathStructure convertFromBaseUnit() const;
94 virtual int baseExponent(int exp = 1) const;
95 virtual int type() const;
96 /** Returns the subtype of the unit, corresponding to which subsubclass the object belongs to.
97 *
98 * @returns ::UnitSubtype.
99 */
100 virtual int subtype() const;
101 /** If specified unit is a base unit for this unit, directly or with other units in between.
102 * Equivalent to u->isParentOf(this).
103 */
104 virtual bool isChildOf(Unit *u) const;
105 /** If this unit is a base unit for specified unit, directly or with other units in between.
106 * Equivalent to u->isChildOf(this).
107 */
108 virtual bool isParentOf(Unit *u) const;
109 virtual bool hasComplexRelationTo(Unit *u) const;
110 /** Converts a value from specified unit and exponent to this unit.
111 * value * (unit^exponent) = new value * (this^new exponent)
112 * This function cannot convert to or from CompositeUnit.
113 *
114 * @param u Unit to convert from.
115 * @param[in,out] mvalue Quantity value.
116 * @param[in,out] exp Exponent.
117 * @returns true if the value was successfully converted.
118 */
119 bool convert(Unit *u, MathStructure &mvalue, MathStructure &exp) const;
120 /** Converts a value from specified unit and exponent to this unit.
121 * value * unit = new value * this
122 * This function cannot convert to or from CompositeUnit.
123 *
124 * @param u Unit to convert from.
125 * @param[in,out] mvalue Quantity value.
126 * @returns true if the value was successfully converted.
127 */
128 bool convert(Unit *u, MathStructure &mvalue) const;
129 MathStructure convert(Unit *u, bool *converted = NULL) const;
130
131};
132
133
134/// An unit with relation to another unit
135/**
136* Alias units is defined in relation to another unit.
137* For example, hour are defined as an alias unit that equals 60 minutes which in turn is defined in relation to seconds.
138*
139* Alias units have an associated base unit, exponent and relation expression.
140* For more complex relations an inverse relation can also be specified for conversion back from the base unit.
141* The base unit must not necessarily be of the base unit class and it is recommended that an alias unit is defined in relation to the closest unit
142* (ex. 1ft = 3 hands, 1 hand = 4 in, and 1 in = 0.0254 m).
143*
144* The relation is usually just a number that tells how large quantity of the base unit is needed to get the alias unit (alias unit = base unit * relation).
145* More complex units can specify the relation as a full-blown expression where '\x' is replaced by the quantity of the base unit and
146* '\y' is the exponent.
147* For example, Degrees Celsius has the relation "\x + 273.15" and the inverse relation "\x - 273.15" to the base unit Kelvin.
148* For simple relations, the reversion is automatic and ought not be defined separately.
149*
150* The precision property inherited from ExpressionItem defines the precision of the relation.
151*
152* The exponent defines the exponential relation to the base unit, so that the alias unit equals the base unit raised to the exponent.
153* For simple unit relations this gives: alias unit = relation * base unit^exponent.
154*
155* Alias units normally have three different names defined for use in expressions - abbreviation (ex. "m"), singular ("meter") and plural ("meters").
156*/
157class AliasUnit : public Unit {
158
159 protected:
160
161 string svalue, sinverse;
162 int i_exp;
163 Unit *o_unit;
164
165 public:
166
167 AliasUnit(string cat_, string name_, string plural_, string singular_, string title_, Unit *alias, string relation = "1", int exp = 1, string inverse = "", bool is_local = true, bool is_builtin = false, bool is_active = true);
168 AliasUnit(const AliasUnit *unit);
169 AliasUnit();
170 virtual ~AliasUnit();
171
172 virtual ExpressionItem *copy() const;
173 virtual void set(const ExpressionItem *item);
174
175 virtual Unit* baseUnit() const;
176 virtual Unit* firstBaseUnit() const;
177 virtual void setBaseUnit(Unit *alias);
178 virtual string expression() const;
179 virtual string inverseExpression() const;
180 /**
181 * Sets the relation expression.
182 */
183 virtual void setExpression(string relation);
184 /**
185 * Sets the inverse relation expression.
186 */
187 virtual void setInverseExpression(string inverse);
188 virtual MathStructure &convertToFirstBaseUnit(MathStructure &mvalue, MathStructure &mexp) const;
189 virtual MathStructure &convertFromFirstBaseUnit(MathStructure &mvalue, MathStructure &mexp) const;
190 virtual MathStructure &convertToBaseUnit(MathStructure &mvalue, MathStructure &mexp) const;
191 virtual MathStructure &convertFromBaseUnit(MathStructure &mvalue, MathStructure &mexp) const;
192 virtual MathStructure &convertToBaseUnit(MathStructure &mvalue) const;
193 virtual MathStructure &convertFromBaseUnit(MathStructure &mvalue) const;
194 virtual MathStructure convertToBaseUnit() const;
195 virtual MathStructure convertFromBaseUnit() const;
196 virtual int baseExponent(int exp = 1) const;
197 virtual void setExponent(int exp);
198 virtual int firstBaseExponent() const;
199 virtual int subtype() const;
200 virtual bool isChildOf(Unit *u) const;
201 virtual bool isParentOf(Unit *u) const;
202 virtual bool hasComplexExpression() const;
203 virtual bool hasComplexRelationTo(Unit *u) const;
204
205};
206
207/// A subunit in a CompositeUnit
208/**
209* Should normally not be used directly.
210*/
211class AliasUnit_Composite : public AliasUnit {
212
213 protected:
214
215 Prefix *prefixv;
216
217 public:
218
219 AliasUnit_Composite(Unit *alias, int exp = 1, Prefix *prefix_ = NULL);
220 AliasUnit_Composite(const AliasUnit_Composite *unit);
221 virtual ~AliasUnit_Composite();
222
223 virtual ExpressionItem *copy() const;
224 virtual void set(const ExpressionItem *item);
225
226 virtual string print(bool plural_, bool short_, bool use_unicode = false, bool (*can_display_unicode_string_function) (const char*, void*) = NULL, void *can_display_unicode_string_arg = NULL) const;
227 virtual Prefix *prefix() const;
228 virtual int prefixExponent() const;
229 virtual void set(Unit *u, int exp = 1, Prefix *prefix_ = NULL);
230 virtual MathStructure &convertToFirstBaseUnit(MathStructure &mvalue, MathStructure &mexp) const;
231 virtual MathStructure &convertFromFirstBaseUnit(MathStructure &mvalue, MathStructure &mexp) const;
232
233};
234
235/// A unit consisting of a number of other units
236/**
237* Composite units are defined by a unit expression with multiple units.
238* Composite units often have an alias unit associated with them, as they do not have a reference name on their own.
239* For example, a joule is defined as an alias defined in relation to a composite unit defined as "Newton * meter".
240*
241* The names of composite units is only used to reference the unit in definitions of other units.
242* They can not be used in expressions.
243*
244* Composite units is definited as a composition of units.
245* The units, with prefixes and exponents, can either be added one by one with add() or
246* parsed from an expression (ex. "cm^3/g) with setBaseExpression().
247*/
248class CompositeUnit : public Unit {
249
250 protected:
251
252 string sshort;
253 vector<AliasUnit_Composite*> units;
254
255 public:
256
257 CompositeUnit(string cat_, string name_, string title_ = "", string base_expression_ = "", bool is_local = true, bool is_builtin = false, bool is_active = true);
258 CompositeUnit(const CompositeUnit *unit);
259 virtual ~CompositeUnit();
260 virtual ExpressionItem *copy() const;
261 virtual void set(const ExpressionItem *item);
262 /** Adds a sub/base unit with specified exponent and an optional prefix.
263 *
264 * @param u Unit.
265 * @param exp Exponent.
266 * @param prefix Prefix.
267 */
268 virtual void add(Unit *u, int exp = 1, Prefix *prefix = NULL);
269 /** Retrieves information about a sub/base unit
270 *
271 * @param index Index starting at 1.
272 * @param[out] exp Exponent.
273 * @param[out] prefix Prefix.
274 * @returns Sub/base unit (AliasUnit_Composite::firstBaseUnit()).
275 */
276 virtual Unit *get(size_t index, int *exp = NULL, Prefix **prefix = NULL) const;
277 virtual void setExponent(size_t index, int exp);
278 virtual void setPrefix(size_t index, Prefix *prefix);
279 /** Returns the number of sub/base units */
280 virtual size_t countUnits() const;
281 virtual size_t find(Unit *u) const;
282 virtual void del(size_t index);
283 /** Prints out the sub/base units with prefixes and exponents.
284 * This is the representation of the unit in expressions.
285 */
286 virtual string print(bool plural_, bool short_, bool use_unicode = false, bool (*can_display_unicode_string_function) (const char*, void*) = NULL, void *can_display_unicode_string_arg = NULL) const;
287 virtual int subtype() const;
288 /** If this unit contains a sub/base unit with a relation to the specified unit.
289 */
290 virtual bool containsRelativeTo(Unit *u) const;
291 /** Creates a MathStructure with the sub/base units of the unit.
292 */
293 virtual MathStructure generateMathStructure(bool make_division = false) const;
294 virtual void setBaseExpression(string base_expression_);
295 /** Removes all sub/base units. */
296 virtual void clear();
297};
298
299
300#endif
301