1 /**
2 * @file UnitDefinition.cpp
3 * @brief Implementations of SBML's UnitDefinition and ListOfUnitDefinitions.
4 * @author Ben Bornstein
5 *
6 * <!--------------------------------------------------------------------------
7 * This file is part of libSBML. Please visit http://sbml.org for more
8 * information about SBML, and the latest version of libSBML.
9 *
10 * Copyright (C) 2020 jointly by the following organizations:
11 * 1. California Institute of Technology, Pasadena, CA, USA
12 * 2. University of Heidelberg, Heidelberg, Germany
13 * 3. University College London, London, UK
14 *
15 * Copyright (C) 2019 jointly by the following organizations:
16 * 1. California Institute of Technology, Pasadena, CA, USA
17 * 2. University of Heidelberg, Heidelberg, Germany
18 *
19 * Copyright (C) 2013-2018 jointly by the following organizations:
20 * 1. California Institute of Technology, Pasadena, CA, USA
21 * 2. EMBL European Bioinformatics Institute (EMBL-EBI), Hinxton, UK
22 * 3. University of Heidelberg, Heidelberg, Germany
23 *
24 * Copyright (C) 2009-2013 jointly by the following organizations:
25 * 1. California Institute of Technology, Pasadena, CA, USA
26 * 2. EMBL European Bioinformatics Institute (EMBL-EBI), Hinxton, UK
27 *
28 * Copyright (C) 2006-2008 by the California Institute of Technology,
29 * Pasadena, CA, USA
30 *
31 * Copyright (C) 2002-2005 jointly by the following organizations:
32 * 1. California Institute of Technology, Pasadena, CA, USA
33 * 2. Japan Science and Technology Agency, Japan
34 *
35 * This library is free software; you can redistribute it and/or modify it
36 * under the terms of the GNU Lesser General Public License as published by
37 * the Free Software Foundation. A copy of the license agreement is provided
38 * in the file named "LICENSE.txt" included with this software distribution
39 * and also available online as http://sbml.org/software/libsbml/license.html
40 * ---------------------------------------------------------------------- -->*/
41
42 #include <sstream>
43
44
45 #include <sbml/xml/XMLNode.h>
46 #include <sbml/xml/XMLAttributes.h>
47 #include <sbml/xml/XMLInputStream.h>
48 #include <sbml/xml/XMLOutputStream.h>
49
50 #include <sbml/units/UnitKindList.h>
51
52 #include <sbml/SBO.h>
53 #include <sbml/SBMLVisitor.h>
54 #include <sbml/SBMLError.h>
55 #include <sbml/SBMLDocument.h>
56 #include <sbml/Unit.h>
57 #include <sbml/UnitDefinition.h>
58 #include <sbml/extension/SBaseExtensionPoint.h>
59
60 #include <sbml/util/ElementFilter.h>
61
62 #include <math.h>
63
64 /** @cond doxygenIgnored */
65 using namespace std;
66 /** @endcond */
67
68 LIBSBML_CPP_NAMESPACE_BEGIN
69 #ifdef __cplusplus
70
UnitDefinition(unsigned int level,unsigned int version)71 UnitDefinition::UnitDefinition (unsigned int level, unsigned int version) :
72 SBase ( level, version )
73 , mUnits (level, version)
74 {
75 if (!hasValidLevelVersionNamespaceCombination())
76 throw SBMLConstructorException();
77
78 connectToChild();
79 }
80
81
UnitDefinition(SBMLNamespaces * sbmlns)82 UnitDefinition::UnitDefinition (SBMLNamespaces * sbmlns) :
83 SBase ( sbmlns )
84 , mUnits (sbmlns)
85 {
86 if (!hasValidLevelVersionNamespaceCombination())
87 {
88 throw SBMLConstructorException(getElementName(), sbmlns);
89 }
90
91 connectToChild();
92 loadPlugins(sbmlns);
93 }
94
95
96 /*
97 * Destroys this UnitDefinition.
98 */
~UnitDefinition()99 UnitDefinition::~UnitDefinition ()
100 {
101 }
102
103
104 /*
105 * Copy constructor. Creates a copy of this UnitDefinition.
106 */
UnitDefinition(const UnitDefinition & orig)107 UnitDefinition::UnitDefinition(const UnitDefinition& orig) :
108 SBase ( orig )
109 , mUnits ( orig.mUnits )
110 {
111 connectToChild();
112 }
113
114
115 /*
116 * Assignment operator.
117 */
operator =(const UnitDefinition & rhs)118 UnitDefinition& UnitDefinition::operator=(const UnitDefinition& rhs)
119 {
120 if(&rhs!=this)
121 {
122 this->SBase::operator =(rhs);
123 mUnits = rhs.mUnits;
124 }
125
126 connectToChild();
127
128 return *this;
129 }
130
131
132 /** @cond doxygenLibsbmlInternal */
133 bool
accept(SBMLVisitor & v) const134 UnitDefinition::accept (SBMLVisitor& v) const
135 {
136 bool result = v.visit(*this);
137 mUnits.accept(v);
138
139 return result;
140 }
141 /** @endcond */
142 \
143
144 /*
145 * @return a (deep) copy of this UnitDefinition.
146 */
147 UnitDefinition*
clone() const148 UnitDefinition::clone () const
149 {
150 return new UnitDefinition(*this);
151 }
152
153
154 SBase*
getElementBySId(const std::string & id)155 UnitDefinition::getElementBySId(const std::string& id)
156 {
157 if (id.empty()) return NULL;
158 SBase* obj = mUnits.getElementBySId(id);
159 if (obj != NULL) return obj;
160
161 return getElementFromPluginsBySId(id);
162 }
163
164
165 SBase*
getElementByMetaId(const std::string & metaid)166 UnitDefinition::getElementByMetaId(const std::string& metaid)
167 {
168 if (metaid.empty()) return NULL;
169 if (mUnits.getMetaId() == metaid) return &mUnits;
170 SBase* obj = mUnits.getElementByMetaId(metaid);
171 if (obj != NULL) return obj;
172
173 return getElementFromPluginsByMetaId(metaid);
174 }
175
176
177 List*
getAllElements(ElementFilter * filter)178 UnitDefinition::getAllElements(ElementFilter *filter)
179 {
180 List* ret = new List();
181 List* sublist = NULL;
182
183 ADD_FILTERED_LIST(ret, sublist, mUnits, filter);
184
185 ADD_FILTERED_FROM_PLUGIN(ret, sublist, filter);
186
187 return ret;
188 }
189
190 /*
191 * @return the id of this SBML object.
192 */
193 const string&
getId() const194 UnitDefinition::getId () const
195 {
196 return mId;
197 }
198
199
200 /*
201 * @return the name of this SBML object.
202 */
203 const string&
getName() const204 UnitDefinition::getName () const
205 {
206 return (getLevel() == 1) ? mId : mName;
207 }
208
209
210 /*
211 * @return @c true if the id of this SBML object is set, false
212 * otherwise.
213 */
214 bool
isSetId() const215 UnitDefinition::isSetId () const
216 {
217 return (mId.empty() == false);
218 }
219
220
221 /*
222 * @return @c true if the name of this SBML object is set, false
223 * otherwise.
224 */
225 bool
isSetName() const226 UnitDefinition::isSetName () const
227 {
228 return (getLevel() == 1) ? (mId.empty() == false) :
229 (mName.empty() == false);
230 }
231
232
233 /*
234 * Sets the id of this SBML object to a copy of @p sid.
235 */
236 int
setId(const std::string & sid)237 UnitDefinition::setId (const std::string& sid)
238 {
239 /* since the setId function has been used as an
240 * alias for setName we can't require it to only
241 * be used on a L2 model
242 */
243 /* if (getLevel() == 1)
244 {
245 return LIBSBML_UNEXPECTED_ATTRIBUTE;
246 }
247 */
248 if (!(SyntaxChecker::isValidInternalSId(sid)))
249 {
250 return LIBSBML_INVALID_ATTRIBUTE_VALUE;
251 }
252 else
253 {
254 mId = sid;
255 return LIBSBML_OPERATION_SUCCESS;
256 }
257 }
258
259
260 /*
261 * Sets the name of this SBML object to a copy of name.
262 */
263 int
setName(const std::string & name)264 UnitDefinition::setName (const std::string& name)
265 {
266 /* if this is setting an L2 name the type is string
267 * whereas if it is setting an L1 name its type is SId
268 */
269 if (getLevel() == 1)
270 {
271 if (!(SyntaxChecker::isValidInternalSId(name)))
272 {
273 return LIBSBML_INVALID_ATTRIBUTE_VALUE;
274 }
275 else
276 {
277 mId = name;
278 return LIBSBML_OPERATION_SUCCESS;
279 }
280 }
281 else
282 {
283 mName = name;
284 return LIBSBML_OPERATION_SUCCESS;
285 }
286 }
287
288
289 /*
290 * Unsets the name of this SBML object.
291 */
292 int
unsetName()293 UnitDefinition::unsetName ()
294 {
295 if (getLevel() == 1)
296 {
297 mId.erase();
298 }
299 else
300 {
301 mName.erase();
302 }
303
304 if (getLevel() == 1 && mId.empty())
305 {
306 return LIBSBML_OPERATION_SUCCESS;
307 }
308 else if (mName.empty())
309 {
310 return LIBSBML_OPERATION_SUCCESS;
311 }
312 else
313 {
314 return LIBSBML_OPERATION_FAILED;
315 }
316 }
317
318
319 /*
320 * @return @c true if this UnitDefinition is a variant of the built-in type
321 * area. i.e. square metres with only arbitrary variations in scale,
322 * or multiplier values, false otherwise.
323 */
324 bool
isVariantOfArea(bool relaxed) const325 UnitDefinition::isVariantOfArea (bool relaxed) const
326 {
327 bool result = false;
328
329 UnitDefinition *ud = static_cast<UnitDefinition*>(this->clone());
330 UnitDefinition::simplify(ud);
331
332 if (!relaxed)
333 {
334 // should be metre^2
335 if (ud->getNumUnits() == 1)
336 {
337 const Unit* u = ud->getUnit(0);
338 result = u->isMetre() && u->getExponent() == 2;
339 }
340 }
341 else
342 {
343 // should be metre
344 if (ud->getNumUnits() == 1)
345 {
346 const Unit* u = ud->getUnit(0);
347 result = u->isMetre();
348 }
349 }
350
351 delete ud;
352 return result;
353 }
354
355
356 /*
357 * @return @c true if this UnitDefinition is a variant of the built-in type
358 * length. i.e. metres with only arbitrary variations in scale,
359 * or multiplier values, false otherwise.
360 */
361 bool
isVariantOfLength(bool relaxed) const362 UnitDefinition::isVariantOfLength (bool relaxed) const
363 {
364 bool result = false;
365
366 UnitDefinition *ud = static_cast<UnitDefinition*>(this->clone());
367 UnitDefinition::simplify(ud);
368
369 if (!relaxed)
370 {
371 //should be metre^1
372 if (ud->getNumUnits() == 1)
373 {
374 const Unit* u = ud->getUnit(0);
375 result = u->isMetre() && u->getExponent() == 1;
376 }
377 }
378 else
379 {
380 //should be metre
381 if (ud->getNumUnits() == 1)
382 {
383 const Unit* u = ud->getUnit(0);
384 result = u->isMetre();
385 }
386 }
387
388 delete ud;
389 return result;
390 }
391
392
393 /*
394 * @return @c true if this UnitDefinition is a variant of the built-in type
395 * substance. i.e. moles or items with only arbitrary variations in
396 * scale or multiplier values, false otherwise.
397 */
398 bool
isVariantOfSubstance(bool relaxed) const399 UnitDefinition::isVariantOfSubstance (bool relaxed) const
400 {
401 bool result = false;
402
403 unsigned int level = getLevel();
404 unsigned int version = getVersion();
405
406 UnitDefinition *ud = static_cast<UnitDefinition*>(this->clone());
407 UnitDefinition::simplify(ud);
408
409 if (!relaxed)
410 {
411 // should be L1/L2V1: mole^1/item^1
412 // L2: mole/item/gram/kilogram ^1
413 // L3: mole/item/gram/kilogram/avogardo ^1
414 if (ud->getNumUnits() == 1)
415 {
416 const Unit* u = ud->getUnit(0);
417 if (level == 2 && version > 1)
418 {
419 result = (( u->isMole() || u->isItem()
420 || u->isGram() || u->isKilogram())
421 && u->getExponent() == 1);
422 }
423 else if (level > 2)
424 {
425 result = (( u->isMole() || u->isItem()
426 || u->isGram() || u->isKilogram()
427 || u->isAvogadro())
428 && u->getExponent() == 1);
429 }
430 else
431 {
432 result = (u->isMole() || u->isItem())
433 && u->getExponent() == 1;
434 }
435 }
436 }
437 else
438 {
439 // should be any combination of mole/item/gram/kilogram/avogardo ^1
440 unsigned int i = 0;
441 result = true;
442 while (result && i < ud->getNumUnits())
443 {
444 const Unit* u = ud->getUnit(i);
445 result = (( u->isMole() || u->isItem()
446 || u->isGram() || u->isKilogram()
447 || u->isAvogadro()));
448
449 i++;
450 }
451 }
452
453 delete ud;
454 return result;
455 }
456
457
458 /*
459 * @return @c true if this UnitDefinition is a variant of the built-in type
460 * time. i.e. seconds with only arbitrary variations in scale,
461 * or multiplier values, false otherwise.
462 */
463 bool
isVariantOfTime(bool relaxed) const464 UnitDefinition::isVariantOfTime (bool relaxed) const
465 {
466 bool result = false;
467
468 UnitDefinition *ud = static_cast<UnitDefinition*>(this->clone());
469 UnitDefinition::simplify(ud);
470
471 if (!relaxed)
472 {
473 // unit should simplify to second with exponent 1
474 if (ud->getNumUnits() == 1)
475 {
476 const Unit* u = ud->getUnit(0);
477 result = u->isSecond() && u->getExponent() == 1;
478 }
479 }
480 else
481 {
482 // from l3v1r2 unit should simplify to second with any exponent
483 if (ud->getNumUnits() == 1)
484 {
485 const Unit* u = ud->getUnit(0);
486 result = u->isSecond();
487 }
488 }
489
490 delete ud;
491 return result;
492 }
493
494
495 /*
496 * @return @c true if this UnitDefinition is a variant of the built-in type
497 * volume. i.e. litre or cubic metre with only arbitrary variations in
498 * scale or multiplier values, false otherwise.
499 */
500 bool
isVariantOfVolume(bool relaxed) const501 UnitDefinition::isVariantOfVolume (bool relaxed) const
502 {
503 bool result = false;
504
505 UnitDefinition *ud = static_cast<UnitDefinition*>(this->clone());
506 UnitDefinition::simplify(ud);
507
508 if (!relaxed)
509 {
510 // should be litre^1 or metre^3
511 if (ud->getNumUnits() == 1)
512 {
513 const Unit* u = ud->getUnit(0);
514 result = (u->isLitre() && u->getExponent() == 1) ||
515 (u->isMetre() && u->getExponent() == 3);
516 }
517 }
518 else
519 {
520 // should be any combination of litre/metre
521 unsigned int i = 0;
522 result = true;
523 while (result && i < ud->getNumUnits())
524 {
525 const Unit* u = ud->getUnit(i);
526 result = ( u->isLitre() || u->isMetre());
527
528 i++;
529 }
530 }
531
532 delete ud;
533 return result;
534 }
535
536
537 /*
538 * @return @c true if this UnitDefinition is a variant of dimensionless.
539 * i.e. dimensionless with only arbitrary variations in scale,
540 * or multiplier values, false otherwise.
541 */
542 bool
isVariantOfDimensionless(bool relaxed) const543 UnitDefinition::isVariantOfDimensionless (bool relaxed) const
544 {
545 bool result = false;
546
547 // careful here if we have no units simplify will add dimensionless
548 if (getNumUnits() == 0)
549 {
550 return result;
551 }
552
553 UnitDefinition *ud = static_cast<UnitDefinition*>(this->clone());
554 UnitDefinition::simplify(ud);
555
556 if (!relaxed)
557 {
558 if (ud->getNumUnits() == 1)
559 {
560 const Unit* u = ud->getUnit(0);
561 result = u->isDimensionless();
562 }
563 }
564 else
565 {
566 if (ud->getNumUnits() == 1)
567 {
568 const Unit* u = ud->getUnit(0);
569 result = u->isDimensionless();
570 }
571 }
572
573 delete ud;
574 return result;
575 }
576
577
578 /*
579 * @return @c true if this UnitDefinition is a variant of mass. ie gram or
580 * kilogram with only arbitrary variations in scale or multiplier
581 * values, false otherwise.
582 */
583 bool
isVariantOfMass(bool relaxed) const584 UnitDefinition::isVariantOfMass (bool relaxed) const
585 {
586 bool result = false;
587
588 UnitDefinition *ud = static_cast<UnitDefinition*>(this->clone());
589 UnitDefinition::simplify(ud);
590
591 if (!relaxed)
592 {
593 // should be gram/kilogram ^ 1
594 if (ud->getNumUnits() == 1)
595 {
596 const Unit* u = ud->getUnit(0);
597 result = ((u->isGram() || u->isKilogram())
598 && u->getExponent() == 1);
599 }
600 }
601 else
602 {
603 // should be any combination of kilogram/gram
604 unsigned int i = 0;
605 result = true;
606 while (result && i < ud->getNumUnits())
607 {
608 const Unit* u = ud->getUnit(i);
609 result = ( u->isGram() || u->isKilogram());
610
611 i++;
612 }
613 }
614
615 delete ud;
616 return result;
617 }
618
619
620 /*
621 * @return @c true if this UnitDefinition is a variant of the built-in type
622 * substance per time, false otherwise.
623 */
624 bool
isVariantOfSubstancePerTime(bool relaxed) const625 UnitDefinition::isVariantOfSubstancePerTime (bool relaxed) const
626 {
627 bool result = false;
628
629 // this unitDefinition times second^1 should be a variant
630 // of substance
631 UnitDefinition *ud = static_cast<UnitDefinition*>(this->clone());
632 //Unit *u = new Unit(UNIT_KIND_SECOND);
633 Unit *u = new Unit(ud->getSBMLNamespaces());
634 u->setKind(UNIT_KIND_SECOND);
635 u->initDefaults();
636 ud->addUnit(u);
637
638 UnitDefinition::simplify(ud);
639
640 result = ud->isVariantOfSubstance(relaxed);
641
642 delete ud;
643 delete u;
644 return result;
645 }
646
647
648 /*
649 * Adds a copy of the given Unit to this UnitDefinition.
650 */
651 int
addUnit(const Unit * u)652 UnitDefinition::addUnit (const Unit* u)
653 {
654 int returnValue = checkCompatibility(static_cast<const SBase *>(u));
655 if (returnValue != LIBSBML_OPERATION_SUCCESS)
656 {
657 return returnValue;
658 }
659 else if (u == NULL)
660 {
661 return LIBSBML_OPERATION_FAILED;
662 }
663 else if (u->hasRequiredAttributes() == false)
664 {
665 return LIBSBML_INVALID_OBJECT;
666 }
667 else if (getLevel() != u->getLevel())
668 {
669 return LIBSBML_LEVEL_MISMATCH;
670 }
671 else if (getVersion() != u->getVersion())
672 {
673 return LIBSBML_VERSION_MISMATCH;
674 }
675 else if (matchesRequiredSBMLNamespacesForAddition(static_cast<const
676 SBase*>(u)) == false)
677 {
678 return LIBSBML_NAMESPACES_MISMATCH;
679 }
680 else
681 {
682 return mUnits.append(u);
683 }
684 }
685
686
687 /*
688 * Creates a new Unit, adds it to this UnitDefinition's list of units and
689 * returns it.
690 */
691 Unit*
createUnit()692 UnitDefinition::createUnit ()
693 {
694 Unit* u = NULL;
695
696 try
697 {
698 u = new Unit(getSBMLNamespaces());
699 }
700 catch (...)
701 {
702 /* here we do not create a default object as the level/version must
703 * match the parent object
704 *
705 * so do nothing
706 */
707 return NULL;
708 }
709
710 if (u != NULL) mUnits.appendAndOwn(u);
711
712 return u;
713 }
714
715
716 /*
717 * @return the list of Units for this UnitDefinition.
718 */
719 const ListOfUnits*
getListOfUnits() const720 UnitDefinition::getListOfUnits () const
721 {
722 return &mUnits;
723 }
724
725
726 /*
727 * @return the list of Units for this UnitDefinition.
728 */
729 ListOfUnits*
getListOfUnits()730 UnitDefinition::getListOfUnits ()
731 {
732 return &mUnits;
733 }
734
735
736 /*
737 * @return the nth Unit of this UnitDefinition
738 */
739 const Unit*
getUnit(unsigned int n) const740 UnitDefinition::getUnit (unsigned int n) const
741 {
742 return static_cast<const Unit*>( mUnits.get(n) );
743 }
744
745
746 /*
747 * @return the nth Unit of this UnitDefinition
748 */
749 Unit*
getUnit(unsigned int n)750 UnitDefinition::getUnit (unsigned int n)
751 {
752 return static_cast<Unit*>( mUnits.get(n) );
753 }
754
755
756 /*
757 * @return the number of Units in this UnitDefinition.
758 */
759 unsigned int
getNumUnits() const760 UnitDefinition::getNumUnits () const
761 {
762 return mUnits.size();
763 }
764
765
766 /**
767 * Removes the nth Unit object from this UnitDefinition object and
768 * returns a pointer to it.
769 */
770 Unit*
removeUnit(unsigned int n)771 UnitDefinition::removeUnit (unsigned int n)
772 {
773 return mUnits.remove(n);
774 }
775
776
777 /** @cond doxygenLibsbmlInternal */
778 /*
779 * Sets the parent SBMLDocument of this SBML object.
780 */
781 void
setSBMLDocument(SBMLDocument * d)782 UnitDefinition::setSBMLDocument (SBMLDocument* d)
783 {
784 SBase::setSBMLDocument(d);
785 mUnits.setSBMLDocument(d);
786 }
787
788
789 /*
790 * Sets this SBML object to child SBML objects (if any).
791 * (Creates a child-parent relationship by the parent)
792 */
793 void
connectToChild()794 UnitDefinition::connectToChild()
795 {
796 SBase::connectToChild();
797 mUnits.connectToParent(this);
798 }
799
800 /**
801 * Enables/Disables the given package with this element and child
802 * elements (if any).
803 * (This is an internal implementation for enablePackage function)
804 */
805 void
enablePackageInternal(const std::string & pkgURI,const std::string & pkgPrefix,bool flag)806 UnitDefinition::enablePackageInternal(const std::string& pkgURI,
807 const std::string& pkgPrefix, bool flag)
808 {
809 SBase::enablePackageInternal(pkgURI,pkgPrefix,flag);
810
811 mUnits.enablePackageInternal(pkgURI,pkgPrefix,flag);
812 }
813
814
815 void
updateSBMLNamespace(const std::string & pkg,unsigned int level,unsigned int version)816 UnitDefinition::updateSBMLNamespace(const std::string& pkg, unsigned int level,
817 unsigned int version)
818 {
819 SBase::updateSBMLNamespace(pkg, level, version);
820
821 mUnits.updateSBMLNamespace(pkg, level, version);
822 }
823 /** @endcond */
824
825
826 /*
827 * @return the typecode (int) of this SBML object or SBML_UNKNOWN
828 * (default).
829 *
830 * @see getElementName()
831 */
832 int
getTypeCode() const833 UnitDefinition::getTypeCode () const
834 {
835 return SBML_UNIT_DEFINITION;
836 }
837
838
839 /*
840 * @return the name of this element ie "unitDefinition".
841 */
842 const string&
getElementName() const843 UnitDefinition::getElementName () const
844 {
845 static const string name = "unitDefinition";
846 return name;
847
848 }
849
850 bool
hasRequiredAttributes() const851 UnitDefinition::hasRequiredAttributes() const
852 {
853 bool allPresent = true;
854
855 /* required attributes for unitDefinition: id (name in L1) */
856
857 if (!isSetId())
858 allPresent = false;
859
860 return allPresent;
861 }
862
863
864 bool
hasRequiredElements() const865 UnitDefinition::hasRequiredElements() const
866 {
867 bool allPresent = true;
868
869 /* required attributes for unitDefinition: listOfUnits (L2 only) */
870
871 if (getLevel() > 1 && getNumUnits() == 0)
872 allPresent = false;
873
874 return allPresent;
875 }
876
877
878 /* utility functions originally in Utils_UnitDefinition
879 * declared as static
880 */
881
882 void
simplify(UnitDefinition * ud)883 UnitDefinition::simplify(UnitDefinition * ud)
884 {
885 if (ud == NULL) return;
886
887 unsigned int n, i;
888 ListOfUnits * units = ud->getListOfUnits();
889 Unit * unit;
890 const char * unitKind;
891 int cancelFlag = 0;
892 bool dimensionlessPresent = false;
893
894
895 for (n = 0; n < ud->getNumUnits(); n++)
896 {
897 Unit* unit = ud->getUnit(n);
898 if (unit->getKind() == UNIT_KIND_DIMENSIONLESS)
899 {
900 dimensionlessPresent = true;
901 }
902 }
903
904 double dimMultfactor = 1.0;
905 double dimMultfactorSaved = 1.0;
906
907
908 /* if only one unit cannot be simplified any further */
909 if (units->size() > 1)
910 {
911 if (dimensionlessPresent)
912 {
913 /* if contains a dimensionless unit and any others then
914 dimensionless is unecessary
915 unless it has a multiplier attached
916 */
917 unsigned int origNumUnits = units->size();
918 for (n = origNumUnits; n > 0; n--)
919 {
920 unit = (Unit *) units->get(n-1);
921 Unit::removeScale(unit);
922
923 if (!strcmp(UnitKind_toString(unit->getKind()), "dimensionless"))
924 {
925 dimMultfactor = pow(unit->getMultiplier(), unit->getExponent());
926 if (util_isEqual(dimMultfactor, 1.0) == false)
927 {
928 cancelFlag = 1;
929 dimMultfactorSaved = dimMultfactorSaved * dimMultfactor;
930 }
931 delete units->remove(n-1);
932 }
933 }
934 }
935
936 /* if it contains two units with same kind these must be combined */
937 for (n = 0; n < units->size(); n++)
938 {
939 unit = (Unit *)units->get(n);
940 unitKind = UnitKind_toString(unit->getKind());
941
942 /* find other occurences and merge */
943 for (i = n+1; i < units->size();)
944 {
945 if (!strcmp(UnitKind_toString(((Unit *)units->get(i))->getKind()),
946 unitKind))
947 {
948 Unit::merge(unit, (Unit *)units->get(i));
949 delete units->remove(i);
950 }
951 else
952 {
953 i++;
954 }
955 }
956 }
957 }
958
959 /* may have cancelled units - in which case exponent will be 0 */
960 // might need to propagate a multiplier though
961 double newMultiplier = dimMultfactorSaved;
962 unsigned int numUnits = units->size();
963 for (n = numUnits; n > 0; n--)
964 {
965 unit = (Unit *) units->get(n-1);
966 if (unit->isUnitChecking())
967 {
968 if (unit->getExponentUnitChecking() == 0)
969 {
970 newMultiplier = newMultiplier * unit->getMultiplier();
971 delete units->remove(n-1);
972 cancelFlag = 1;
973 }
974 }
975 else if (unit->getExponent() == 0)
976 {
977 newMultiplier = newMultiplier * unit->getMultiplier();
978 delete units->remove(n-1);
979 cancelFlag = 1;
980 }
981 }
982
983 /* if all units have been cancelled need to add dimensionless */
984 /* or indeed if one or more have been cancelled need to
985 * propagate any remaining multiplier */
986 if (cancelFlag == 1 || (dimensionlessPresent && units->size() == 0))
987 {
988 if (units->size() == 0)
989 {
990 Unit tmpunit(ud->getSBMLNamespaces());
991 tmpunit.setKind(UNIT_KIND_DIMENSIONLESS);
992 tmpunit.initDefaults();
993 tmpunit.setMultiplier(newMultiplier);
994 ud->addUnit(&tmpunit);
995 }
996 else if (util_isEqual(newMultiplier, 1.0) == false)
997 {
998 unit = units->get(0);
999 unit->setMultiplier(unit->getMultiplier() *
1000 pow(newMultiplier, 1.0/unit->getExponentAsDouble()));
1001 }
1002 }
1003
1004 }
1005
1006 /** @cond doxygenLibsbmlInternal */
compareKinds(const void * u1,const void * u2)1007 int compareKinds(const void * u1, const void * u2)
1008 {
1009 return (*(int*)u1 - *(int*)u2);
1010 }
1011 /** @endcond */
1012
1013 /*
1014 * Orders the listOfUnits within the UnitDefinition alphabetically.
1015 *
1016 * @param ud the UnitDefinition object to be ordered.
1017 */
1018 void
reorder(UnitDefinition * ud)1019 UnitDefinition::reorder(UnitDefinition *ud)
1020 {
1021 if (ud == NULL) return;
1022
1023 unsigned int n, p;
1024 ListOfUnits * units = ud->getListOfUnits();
1025 Unit * unit;
1026 unsigned int numUnits = units->size();
1027
1028 int *indexArray = NULL;
1029 indexArray = new int[units->size()];
1030
1031 int *initialIndexArray = NULL;
1032 initialIndexArray = new int[units->size()];
1033
1034 std::vector<unsigned int> used;
1035
1036 for (n = 0; n < numUnits; n++)
1037 {
1038 unit = (Unit *)(units->get(n));
1039 int value = (int)(unit->getKind());
1040 indexArray[n] = value;
1041 initialIndexArray[n] = value;
1042 }
1043
1044 qsort(indexArray, numUnits, sizeof(int), compareKinds);
1045
1046 /* append units in correct order */
1047 for (n = 0; n < numUnits; n++)
1048 {
1049 for (p = 0; p < numUnits; p++)
1050 {
1051 if (indexArray[n] == initialIndexArray[p])
1052 {
1053 if (used.end() == std::find(used.begin(), used.end(), p))
1054 {
1055 unit = (Unit *) units->get(p);
1056 units->append(unit);
1057 used.push_back(p);
1058 break;
1059 }
1060 }
1061 }
1062 }
1063
1064 /* remove originals */
1065 for (n = 0; n < numUnits; n++)
1066 {
1067 delete units->remove(0);
1068 }
1069
1070 delete [] indexArray;
1071 delete [] initialIndexArray;
1072 }
1073
1074
1075 /*
1076 * Returns a UnitDefinition object which is the argument UnitDefinition
1077 * converted to the SI units.
1078 *
1079 * @param ud the UnitDefinition object to convert to SI.
1080 *
1081 * @return a UnitDefinition object converted to SI units.
1082 */
1083 UnitDefinition *
convertToSI(const UnitDefinition * ud)1084 UnitDefinition::convertToSI(const UnitDefinition * ud)
1085 {
1086 if (ud == NULL) return NULL;
1087
1088 unsigned int n, p;
1089 UnitDefinition * newUd = new UnitDefinition(ud->getSBMLNamespaces());
1090 UnitDefinition * tempUd;
1091 Unit * tempUnit;
1092
1093 newUd->setId(ud->getId());
1094 newUd->setName(ud->getName());
1095
1096 for (n = 0; n < ud->getNumUnits(); n++)
1097 {
1098 tempUd = Unit::convertToSI(ud->getUnit(n));
1099 for (p = 0; p < tempUd->getNumUnits(); p++)
1100 {
1101 tempUnit = new Unit(ud->getSBMLNamespaces());
1102 tempUnit->setKind(tempUd->getUnit(p)->getKind());
1103 if (tempUd->getUnit(p)->isUnitChecking())
1104 {
1105 tempUnit->setExponentUnitChecking(tempUd->getUnit(p)->getExponentUnitChecking());
1106 }
1107 else
1108 {
1109 tempUnit->setExponent(tempUd->getUnit(p)->getExponent());
1110 }
1111 tempUnit->setScale(tempUd->getUnit(p)->getScale());
1112 tempUnit->setMultiplier(tempUd->getUnit(p)->getMultiplier());
1113 newUd->addUnit(tempUnit);
1114 delete tempUnit;
1115 }
1116 delete tempUd;
1117 }
1118
1119 UnitDefinition::simplify(newUd);
1120 return newUd;
1121 }
1122
1123
1124 double
extractMultiplier(UnitDefinition * ud)1125 extractMultiplier(UnitDefinition * ud)
1126 {
1127 double multiplier = 1.0;
1128
1129 unsigned int i = 0;
1130 while(i < ud->getNumUnits())
1131 {
1132 Unit::removeScale(ud->getUnit(i));
1133 multiplier = multiplier * pow(ud->getUnit(i)->getMultiplier(),
1134 ud->getUnit(i)->getExponentAsDouble());
1135 ud->getUnit(i)->setMultiplier(1.0);
1136 ud->getUnit(i)->setScale(0);
1137 i++;
1138 }
1139 return multiplier;
1140 }
1141
1142
1143 ///* slightly less restrictive version that util_isEqual
1144 // * I had issues with this when one of the multipliers
1145 // * had not been calculated and was just 1.0
1146 // */
1147 //bool
1148 //isEqual(double a, double b)
1149 //{
1150 // double tol;
1151 // if (a < b)
1152 // tol = a * 1e-10;
1153 // else
1154 // tol = b * 1e-10;
1155 // return (fabs(a-b) < sqrt(tol)) ? true : false;
1156 //}
1157
1158
1159 /*
1160 * Predicate returning @c true if
1161 * UnitDefinition objects are identical (all units are identical).
1162 *
1163 * @param ud1 the first UnitDefinition object to compare.
1164 * @param ud2 the second UnitDefinition object to compare.
1165 *
1166 * @return @c true if all the units of ud1 are identical
1167 * to the units of ud2, @c false otherwise.
1168 *
1169 * @note For the purposes of comparison two units can be "identical",
1170 * i.e. all attributes are an exact match, or "equivalent" i.e.
1171 * matching kind and exponent.
1172 *
1173 * @see areEquivalent();
1174 */
1175 bool
areIdentical(const UnitDefinition * ud1,const UnitDefinition * ud2)1176 UnitDefinition::areIdentical(const UnitDefinition * ud1,
1177 const UnitDefinition * ud2)
1178 {
1179 bool identical = false;
1180
1181 bool A = (ud1 == NULL);
1182 bool B = (ud2 == NULL);
1183
1184 /* if one or other is NULL no need to check
1185 */
1186 if ((A || B) && !(A && B))
1187 {
1188 return identical;
1189 }
1190
1191 /* if both NULL no need to check */
1192 if (A && B)
1193 {
1194 identical = true;
1195 return identical;
1196 }
1197
1198 /* must be same level/version/ namespace
1199 */
1200 if ( (ud1->getLevel() != ud2->getLevel()) ||
1201 (ud1->getVersion() != ud2->getVersion()))
1202 {
1203 return identical;
1204 }
1205 unsigned int n;
1206
1207 /* need to order the unitDefinitions so must make copies
1208 * since the arguments are const
1209 */
1210 UnitDefinition * ud1Temp = new UnitDefinition(ud1->getSBMLNamespaces());
1211 UnitDefinition * ud2Temp = new UnitDefinition(ud2->getSBMLNamespaces());
1212
1213 for ( n = 0; n < ud1->getNumUnits(); n++)
1214 ud1Temp->addUnit(ud1->getUnit(n));
1215 for ( n = 0; n < ud2->getNumUnits(); n++)
1216 ud2Temp->addUnit(ud2->getUnit(n));
1217
1218 UnitDefinition::simplify(ud1Temp);
1219 UnitDefinition::simplify(ud2Temp);
1220
1221 if (ud1Temp->getNumUnits() == ud2Temp->getNumUnits())
1222 {
1223 UnitDefinition::reorder(ud1Temp);
1224 UnitDefinition::reorder(ud2Temp);
1225
1226 if (ud1Temp->getNumUnits() > 1)
1227 {
1228 // different multipliers left on different units may not match
1229 // but overall they
1230 // e.g (2m)(sec) is tha same unit as (m)(2sec) but unit by unit
1231 // comparison will fail
1232 double multiplier1 = extractMultiplier(ud1Temp);
1233 double multiplier2 = extractMultiplier(ud2Temp);
1234
1235 if (util_isEqual(multiplier1, multiplier2) == false)
1236 {
1237 return identical;
1238 }
1239 }
1240
1241 n = 0;
1242 while (n < ud1Temp->getNumUnits())
1243 {
1244 if (!Unit::areIdentical(ud1Temp->getUnit(n), ud2Temp->getUnit(n)))
1245 {
1246 break;
1247 }
1248 else
1249 {
1250 n++;
1251 }
1252 }
1253 if (n == ud1Temp->getNumUnits())
1254 {
1255 identical = true;
1256 }
1257 }
1258
1259 delete ud1Temp;
1260 delete ud2Temp;
1261
1262 return identical;
1263 }
1264
1265
1266 /*
1267 * Predicate returning @c true if
1268 * UnitDefinition objects are equivalent (all units are equivalent).
1269 *
1270 * @param ud1 the first UnitDefinition object to compare.
1271 * @param ud2 the second UnitDefinition object to compare.
1272 *
1273 * @return @c true if all the units of ud1 are equivalent
1274 * to the units of ud2, @c false otherwise.
1275 *
1276 * @note For the purposes of comparison two units can be "identical",
1277 * i.e. all attributes are an exact match, or "equivalent" i.e.
1278 * matching kind and exponent.
1279 *
1280 * @see areIdentical();
1281 */
1282 bool
areEquivalent(const UnitDefinition * ud1,const UnitDefinition * ud2)1283 UnitDefinition::areEquivalent(const UnitDefinition * ud1, const UnitDefinition * ud2)
1284 {
1285 bool equivalent = false;
1286
1287 bool A = (ud1 == NULL);
1288 bool B = (ud2 == NULL);
1289
1290 /* if one or other is NULL no need to check
1291 */
1292 if ((A || B) && !(A && B))
1293 {
1294 return equivalent;
1295 }
1296
1297 /* if both NULL no need to check */
1298 if (A && B)
1299 {
1300 equivalent = true;
1301 return equivalent;
1302 }
1303
1304 unsigned int n;
1305
1306 UnitDefinition * ud1Temp = UnitDefinition::convertToSI(ud1);
1307 UnitDefinition * ud2Temp = UnitDefinition::convertToSI(ud2);
1308
1309 if (ud1Temp->getNumUnits() == ud2Temp->getNumUnits())
1310 {
1311 UnitDefinition::reorder(ud1Temp);
1312 UnitDefinition::reorder(ud2Temp);
1313
1314 n = 0;
1315 while (n < ud1Temp->getNumUnits())
1316 {
1317 if (!Unit::areEquivalent(ud1Temp->getUnit(n), ud2Temp->getUnit(n)))
1318 {
1319 break;
1320 }
1321 else
1322 {
1323 n++;
1324 }
1325 }
1326 if (n == ud1Temp->getNumUnits())
1327 {
1328 equivalent = true;
1329 }
1330 }
1331
1332 delete ud1Temp;
1333 delete ud2Temp;
1334
1335 return equivalent;
1336 }
1337
1338 /** @cond doxygenLibsbmlInternal */
1339 bool
areIdenticalSIUnits(const UnitDefinition * ud1,const UnitDefinition * ud2)1340 UnitDefinition::areIdenticalSIUnits(const UnitDefinition * ud1,
1341 const UnitDefinition * ud2)
1342 {
1343 bool identical = false;
1344
1345 bool A = (ud1 == NULL);
1346 bool B = (ud2 == NULL);
1347
1348 /* if one or other is NULL no need to check
1349 */
1350 if ((A || B) && !(A && B))
1351 {
1352 return identical;
1353 }
1354
1355 /* if both NULL no need to check */
1356 if (A && B)
1357 {
1358 identical = true;
1359 return identical;
1360 }
1361
1362 unsigned int n;
1363
1364 /* need to order the unitDefinitions so must make copies
1365 * since the arguments are const
1366 */
1367 UnitDefinition * ud1Temp = UnitDefinition::convertToSI(ud1);
1368 UnitDefinition * ud2Temp = UnitDefinition::convertToSI(ud2);
1369
1370 if (ud1Temp->getNumUnits() == ud2Temp->getNumUnits())
1371 {
1372 UnitDefinition::reorder(ud1Temp);
1373 UnitDefinition::reorder(ud2Temp);
1374
1375 if (ud1Temp->getNumUnits() > 1)
1376 {
1377 // different multipliers left on different units may not match
1378 // but overall they
1379 // e.g (2m)(sec) is tha same unit as (m)(2sec) but unit by unit
1380 // comparison will fail
1381 double multiplier1 = extractMultiplier(ud1Temp);
1382 double multiplier2 = extractMultiplier(ud2Temp);
1383
1384 if (util_isEqual(multiplier1, multiplier2) == false)
1385 {
1386 delete ud1Temp;
1387 delete ud2Temp;
1388 return identical;
1389 }
1390 }
1391
1392 n = 0;
1393 while (n < ud1Temp->getNumUnits())
1394 {
1395 Unit* u1 = ud1Temp->getUnit(n);
1396 Unit* u2 = ud2Temp->getUnit(n);
1397 // if the unit is dimensionless it does not matter
1398 // what numerical factors it has
1399 // but put this check here rather than in the unit areIdentical
1400 // so that Unit::areIdentical is trully a test for identical
1401 if (u1->getKind() == UNIT_KIND_DIMENSIONLESS)
1402 {
1403 if (u2->getKind() != UNIT_KIND_DIMENSIONLESS)
1404 {
1405 break;
1406 }
1407 else
1408 {
1409 n++;
1410 }
1411 }
1412 else
1413 {
1414 if (!Unit::areIdentical(u1, u2))
1415 {
1416 break;
1417 }
1418 else
1419 {
1420 n++;
1421 }
1422 }
1423 }
1424 if (n == ud1Temp->getNumUnits())
1425 {
1426 identical = true;
1427 }
1428 }
1429
1430 delete ud1Temp;
1431 delete ud2Temp;
1432
1433 return identical;
1434 }
1435 /** @endcond */
1436
1437 /*
1438 * Combines two UnitDefinition objects into a single UnitDefinition object
1439 * which expresses the units of the two objects multiplied.
1440 *
1441 * @param ud1 the first UnitDefinition object into which the second is
1442 * combined.
1443 * @param ud2 the second UnitDefinition object.
1444 */
1445 UnitDefinition *
combine(UnitDefinition * ud1,UnitDefinition * ud2)1446 UnitDefinition::combine(UnitDefinition *ud1, UnitDefinition *ud2)
1447 {
1448 bool A = (ud1 == NULL);
1449 bool B = (ud2 == NULL);
1450
1451 UnitDefinition * ud;
1452
1453 if (A && B)
1454 {
1455 ud = NULL;
1456 }
1457 else if (A && !B)
1458 {
1459 ud = new UnitDefinition(*ud2);
1460 }
1461 else if (B && !A)
1462 {
1463 ud = new UnitDefinition(*ud1);
1464 }
1465 else if ( (ud1->getLevel() != ud2->getLevel()) ||
1466 (ud1->getVersion() != ud2->getVersion()))
1467 {
1468 ud = NULL;
1469 }
1470 else
1471 {
1472 ud = new UnitDefinition(*ud1);
1473 for (unsigned int n = 0; n < ud2->getNumUnits(); n++)
1474 {
1475 ud->addUnit(ud2->getUnit(n));
1476 }
1477
1478 UnitDefinition::simplify(ud);
1479 }
1480 return ud;
1481 }
1482
1483
1484 UnitDefinition *
divide(UnitDefinition * ud1,UnitDefinition * ud2)1485 UnitDefinition::divide(UnitDefinition *ud1, UnitDefinition *ud2)
1486 {
1487 bool A = (ud1 == NULL);
1488 bool B = (ud2 == NULL);
1489
1490 UnitDefinition * ud = NULL;
1491
1492 if (A && B)
1493 {
1494 ud = NULL;
1495 }
1496 else if (A && !B)
1497 {
1498 // no longer true
1499 ud = new UnitDefinition(*ud2);
1500 for (unsigned int i = 0; i < ud->getNumUnits(); i++)
1501 {
1502 ud->getUnit(i)->setExponent(ud->getUnit(i)->getExponent() * -1);
1503 }
1504 }
1505 else if (B && !A)
1506 {
1507 ud = new UnitDefinition(*ud1);
1508 }
1509 else if ( (ud1->getLevel() != ud2->getLevel()) ||
1510 (ud1->getVersion() != ud2->getVersion()))
1511 {
1512 ud = NULL;
1513 }
1514 else
1515 {
1516 ud = new UnitDefinition(*ud1);
1517 for (unsigned int n = 0; n < ud2->getNumUnits(); n++)
1518 {
1519 Unit * u = new Unit(*(ud2->getUnit(n)));
1520 u->setExponent(u->getExponent() * -1);
1521 ud->addUnit(u);
1522 delete u;
1523 }
1524
1525 UnitDefinition::simplify(ud);
1526 }
1527 return ud;
1528 }
1529
1530 /*
1531 * Returns a string that expresses the units symbolised by the UnitDefinition.
1532 * For example printUnits applied to
1533 * @code
1534 * <unitDefinition>
1535 * <listOfUnits>
1536 * <unit kind="metre" exponent="1"/>
1537 * <unit kind="second" exponent="-2"/>
1538 * </listOfUnits>
1539 * <unitDefinition>
1540 * @endcode
1541 * returns the string 'metre (exponent = 1) second (exponent = -2)'
1542 *
1543 * @param ud the UnitDefinition object.
1544 *
1545 * @return a string expressing the units.
1546 */
1547 std::string
printUnits(const UnitDefinition * ud,bool compact)1548 UnitDefinition::printUnits(const UnitDefinition * ud, bool compact)
1549 {
1550 std::stringstream unitDef;
1551 if (ud == NULL || ud->getNumUnits() == 0)
1552 {
1553 unitDef << "indeterminable";
1554 }
1555 else
1556 {
1557 if (!compact)
1558 {
1559 for (unsigned int p = 0; p < ud->getNumUnits(); p++)
1560 {
1561 UnitKind_t kind = ud->getUnit(p)->getKind();
1562 double exp = 0;
1563 if (ud->getUnit(p)->isUnitChecking())
1564 {
1565 exp = ud->getUnit(p)->getExponentUnitChecking();
1566 }
1567 else
1568 {
1569 exp = ud->getUnit(p)->getExponentAsDouble();
1570 }
1571 int scale = ud->getUnit(p)->getScale();
1572 double mult = ud->getUnit(p)->getMultiplier();
1573
1574 unitDef << UnitKind_toString(kind) << " (exponent = " << exp
1575 << ", multiplier = " << mult << ", scale = " << scale << ")";
1576
1577 if (p + 1 < ud->getNumUnits())
1578 {
1579 unitDef << ", ";
1580 }
1581 }
1582 }
1583 else
1584 {
1585 for (unsigned int p = 0; p < ud->getNumUnits(); p++)
1586 {
1587 UnitKind_t kind = ud->getUnit(p)->getKind();
1588 double exp = ud->getUnit(p)->getExponentAsDouble();
1589 int scale = ud->getUnit(p)->getScale();
1590 double mult = ud->getUnit(p)->getMultiplier();
1591 mult = mult * pow(10.0, scale);
1592
1593 unitDef << "(" << mult << " " << UnitKind_toString(kind) << ")^" << exp;
1594
1595 if (p + 1 < ud->getNumUnits())
1596 {
1597 unitDef << ", ";
1598 }
1599 }
1600 }
1601 }
1602 return unitDef.str();
1603 }
1604 /** @cond doxygenLibsbmlInternal */
1605
1606 /*
1607 * Returns the value of the "attributeName" attribute of this UnitDefinition.
1608 */
1609 int
getAttribute(const std::string & attributeName,bool & value) const1610 UnitDefinition::getAttribute(const std::string& attributeName,
1611 bool& value) const
1612 {
1613 int return_value = SBase::getAttribute(attributeName, value);
1614
1615 return return_value;
1616 }
1617
1618 /** @endcond */
1619
1620
1621
1622 /** @cond doxygenLibsbmlInternal */
1623
1624 /*
1625 * Returns the value of the "attributeName" attribute of this UnitDefinition.
1626 */
1627 int
getAttribute(const std::string & attributeName,int & value) const1628 UnitDefinition::getAttribute(const std::string& attributeName,
1629 int& value) const
1630 {
1631 int return_value = SBase::getAttribute(attributeName, value);
1632
1633 return return_value;
1634 }
1635
1636 /** @endcond */
1637
1638
1639
1640 /** @cond doxygenLibsbmlInternal */
1641
1642 /*
1643 * Returns the value of the "attributeName" attribute of this UnitDefinition.
1644 */
1645 int
getAttribute(const std::string & attributeName,double & value) const1646 UnitDefinition::getAttribute(const std::string& attributeName,
1647 double& value) const
1648 {
1649 int return_value = SBase::getAttribute(attributeName, value);
1650
1651 return return_value;
1652 }
1653
1654 /** @endcond */
1655
1656
1657
1658 /** @cond doxygenLibsbmlInternal */
1659
1660 /*
1661 * Returns the value of the "attributeName" attribute of this UnitDefinition.
1662 */
1663 int
getAttribute(const std::string & attributeName,unsigned int & value) const1664 UnitDefinition::getAttribute(const std::string& attributeName,
1665 unsigned int& value) const
1666 {
1667 int return_value = SBase::getAttribute(attributeName, value);
1668
1669 return return_value;
1670 }
1671
1672 /** @endcond */
1673
1674
1675
1676 /** @cond doxygenLibsbmlInternal */
1677
1678 /*
1679 * Returns the value of the "attributeName" attribute of this UnitDefinition.
1680 */
1681 int
getAttribute(const std::string & attributeName,std::string & value) const1682 UnitDefinition::getAttribute(const std::string& attributeName,
1683 std::string& value) const
1684 {
1685 int return_value = SBase::getAttribute(attributeName, value);
1686
1687 return return_value;
1688 }
1689
1690 /** @endcond */
1691
1692
1693
1694 /** @cond doxygenLibsbmlInternal */
1695
1696 /*
1697 * Returns the value of the "attributeName" attribute of this UnitDefinition.
1698 */
1699 //int
1700 //UnitDefinition::getAttribute(const std::string& attributeName,
1701 // const char* value) const
1702 //{
1703 // int return_value = SBase::getAttribute(attributeName, value);
1704 //
1705 // return return_value;
1706 //}
1707
1708 /** @endcond */
1709
1710
1711
1712 /** @cond doxygenLibsbmlInternal */
1713
1714 /*
1715 * Predicate returning @c true if this UnitDefinition's attribute
1716 * "attributeName" is set.
1717 */
1718 bool
isSetAttribute(const std::string & attributeName) const1719 UnitDefinition::isSetAttribute(const std::string& attributeName) const
1720 {
1721 bool value = SBase::isSetAttribute(attributeName);
1722
1723 return value;
1724 }
1725
1726 /** @endcond */
1727
1728
1729
1730 /** @cond doxygenLibsbmlInternal */
1731
1732 /*
1733 * Sets the value of the "attributeName" attribute of this UnitDefinition.
1734 */
1735 int
setAttribute(const std::string & attributeName,bool value)1736 UnitDefinition::setAttribute(const std::string& attributeName, bool value)
1737 {
1738 int return_value = SBase::setAttribute(attributeName, value);
1739
1740 return return_value;
1741 }
1742
1743 /** @endcond */
1744
1745
1746
1747 /** @cond doxygenLibsbmlInternal */
1748
1749 /*
1750 * Sets the value of the "attributeName" attribute of this UnitDefinition.
1751 */
1752 int
setAttribute(const std::string & attributeName,int value)1753 UnitDefinition::setAttribute(const std::string& attributeName, int value)
1754 {
1755 int return_value = SBase::setAttribute(attributeName, value);
1756
1757 return return_value;
1758 }
1759
1760 /** @endcond */
1761
1762
1763
1764 /** @cond doxygenLibsbmlInternal */
1765
1766 /*
1767 * Sets the value of the "attributeName" attribute of this UnitDefinition.
1768 */
1769 int
setAttribute(const std::string & attributeName,double value)1770 UnitDefinition::setAttribute(const std::string& attributeName, double value)
1771 {
1772 int return_value = SBase::setAttribute(attributeName, value);
1773
1774 return return_value;
1775 }
1776
1777 /** @endcond */
1778
1779
1780
1781 /** @cond doxygenLibsbmlInternal */
1782
1783 /*
1784 * Sets the value of the "attributeName" attribute of this UnitDefinition.
1785 */
1786 int
setAttribute(const std::string & attributeName,unsigned int value)1787 UnitDefinition::setAttribute(const std::string& attributeName,
1788 unsigned int value)
1789 {
1790 int return_value = SBase::setAttribute(attributeName, value);
1791
1792 return return_value;
1793 }
1794
1795 /** @endcond */
1796
1797
1798
1799 /** @cond doxygenLibsbmlInternal */
1800
1801 /*
1802 * Sets the value of the "attributeName" attribute of this UnitDefinition.
1803 */
1804 int
setAttribute(const std::string & attributeName,const std::string & value)1805 UnitDefinition::setAttribute(const std::string& attributeName,
1806 const std::string& value)
1807 {
1808 int return_value = SBase::setAttribute(attributeName, value);
1809
1810 return return_value;
1811 }
1812
1813 /** @endcond */
1814
1815
1816
1817 /** @cond doxygenLibsbmlInternal */
1818
1819 /*
1820 * Sets the value of the "attributeName" attribute of this UnitDefinition.
1821 */
1822 //int
1823 //UnitDefinition::setAttribute(const std::string& attributeName,
1824 // const char* value)
1825 //{
1826 // int return_value = SBase::setAttribute(attributeName, value);
1827 //
1828 // return return_value;
1829 //}
1830 //
1831 /** @endcond */
1832
1833
1834
1835 /** @cond doxygenLibsbmlInternal */
1836
1837 /*
1838 * Unsets the value of the "attributeName" attribute of this UnitDefinition.
1839 */
1840 int
unsetAttribute(const std::string & attributeName)1841 UnitDefinition::unsetAttribute(const std::string& attributeName)
1842 {
1843 int value = SBase::unsetAttribute(attributeName);
1844
1845 return value;
1846 }
1847 /** @endcond */
1848
1849
1850
1851 /** @cond doxygenLibsbmlInternal */
1852 /*
1853 * Creates and returns an new "elementName" object in this UnitDefinition.
1854 */
1855 SBase*
createChildObject(const std::string & elementName)1856 UnitDefinition::createChildObject(const std::string& elementName)
1857 {
1858 SBase* obj = NULL;
1859
1860 if (elementName == "unit")
1861 {
1862 return createUnit();
1863 }
1864
1865 return obj;
1866 }
1867 /** @endcond */
1868
1869 /** @cond doxygenLibsbmlInternal */
1870 /*
1871 * Adds an new "elementName" object in this UnitDefinition.
1872 */
1873 int
addChildObject(const std::string & elementName,const SBase * element)1874 UnitDefinition::addChildObject(const std::string& elementName, const SBase* element)
1875 {
1876 if (elementName == "unit" && element->getTypeCode() == SBML_UNIT)
1877 {
1878 return addUnit((const Unit*)(element));
1879 }
1880
1881 return LIBSBML_OPERATION_FAILED;
1882 }
1883 /** @endcond */
1884
1885
1886 /** @cond doxygenLibsbmlInternal */
1887 /*
1888 * Adds an new "elementName" object in this UnitDefinition.
1889 */
1890 SBase*
removeChildObject(const std::string & elementName,const std::string & id)1891 UnitDefinition::removeChildObject(const std::string& elementName, const std::string& id)
1892 {
1893
1894 if (elementName == "unit")
1895 {
1896 // return removeUnit(id);
1897 }
1898
1899 return NULL;
1900 }
1901
1902 /** @endcond */
1903
1904
1905
1906
1907 /** @cond doxygenLibsbmlInternal */
1908
1909 /*
1910 * Returns the number of "elementName" in this UnitDefinition.
1911 */
1912 unsigned int
getNumObjects(const std::string & elementName)1913 UnitDefinition::getNumObjects(const std::string& elementName)
1914 {
1915 unsigned int n = 0;
1916
1917 if (elementName == "unit")
1918 {
1919 return getNumUnits();
1920 }
1921
1922 return n;
1923 }
1924
1925 /** @endcond */
1926
1927
1928
1929 /** @cond doxygenLibsbmlInternal */
1930
1931 /*
1932 * Returns the nth object of "objectName" in this UnitDefinition.
1933 */
1934 SBase*
getObject(const std::string & elementName,unsigned int index)1935 UnitDefinition::getObject(const std::string& elementName, unsigned int index)
1936 {
1937 SBase* obj = NULL;
1938
1939 if (elementName == "unit")
1940 {
1941 return getUnit(index);
1942 }
1943
1944 return obj;
1945 }
1946
1947 /** @endcond */
1948
1949
1950
1951 /* @cond doxygenLibsbmlInternal */
1952 /*
1953 * @return the SBML object corresponding to next XMLToken in the
1954 * XMLInputStream or @c NULL if the token was not recognized.
1955 */
1956 SBase*
createObject(XMLInputStream & stream)1957 UnitDefinition::createObject (XMLInputStream& stream)
1958 {
1959 SBase* object = 0;
1960
1961 const string& name = stream.peek().getName();
1962 if (name == "listOfUnits")
1963 {
1964 if (mUnits.size() != 0)
1965 {
1966 if (getLevel() < 3)
1967 {
1968 logError(NotSchemaConformant, getLevel(), getVersion(),
1969 "Only one <listOfUnits> elements is permitted in a "
1970 "given <unitDefinition>.");
1971 }
1972 else
1973 {
1974 logError(OneListOfUnitsPerUnitDef, getLevel(), getVersion());
1975 }
1976 }
1977 mUnits.setExplicitlyListed();
1978 object = &mUnits;
1979 }
1980
1981 return object;
1982 }
1983 /** @endcond */
1984
1985
1986 /** @cond doxygenLibsbmlInternal */
1987 /*
1988 * Subclasses should override this method to get the list of
1989 * expected attributes.
1990 * This function is invoked from corresponding readAttributes()
1991 * function.
1992 */
1993 void
addExpectedAttributes(ExpectedAttributes & attributes)1994 UnitDefinition::addExpectedAttributes(ExpectedAttributes& attributes)
1995 {
1996 SBase::addExpectedAttributes(attributes);
1997
1998 const unsigned int level = getLevel ();
1999
2000 attributes.add("name");
2001
2002 if (level > 1)
2003 {
2004 attributes.add("id");
2005 }
2006 }
2007
2008
2009 /*
2010 * Subclasses should override this method to read values from the given
2011 * XMLAttributes set into their specific fields. Be sure to call your
2012 * parent's implementation of this method as well.
2013 */
2014 void
readAttributes(const XMLAttributes & attributes,const ExpectedAttributes & expectedAttributes)2015 UnitDefinition::readAttributes (const XMLAttributes& attributes,
2016 const ExpectedAttributes& expectedAttributes)
2017 {
2018 const unsigned int level = getLevel ();
2019
2020 SBase::readAttributes(attributes, expectedAttributes);
2021
2022 switch (level)
2023 {
2024 case 1:
2025 readL1Attributes(attributes);
2026 break;
2027 case 2:
2028 readL2Attributes(attributes);
2029 break;
2030 case 3:
2031 default:
2032 readL3Attributes(attributes);
2033 break;
2034 }
2035 }
2036 /** @endcond */
2037
2038
2039 /** @cond doxygenLibsbmlInternal */
2040 /*
2041 * Subclasses should override this method to read values from the given
2042 * XMLAttributes set into their specific fields. Be sure to call your
2043 * parent's implementation of this method as well.
2044 */
2045 void
readL1Attributes(const XMLAttributes & attributes)2046 UnitDefinition::readL1Attributes (const XMLAttributes& attributes)
2047 {
2048 const unsigned int level = getLevel();
2049 const unsigned int version = getVersion();
2050
2051 //
2052 // name: SName { use="required" } (L1v1, L1v2)
2053 // id: SId { use="required" } (L2v1, L2v2)
2054 //
2055 bool assigned;
2056 assigned = attributes.readInto("name", mId, getErrorLog(), true, getLine(), getColumn());
2057 if (assigned && mId.size() == 0)
2058 {
2059 logEmptyString("name", level, version, "<unitDefinition>");
2060 }
2061 if (!SyntaxChecker::isValidInternalSId(mId))
2062 logError(InvalidIdSyntax, level, version, "The id '" + mId + "' does not conform to the syntax.");
2063 }
2064 /** @endcond */
2065
2066
2067 /** @cond doxygenLibsbmlInternal */
2068 /*
2069 * Subclasses should override this method to read values from the given
2070 * XMLAttributes set into their specific fields. Be sure to call your
2071 * parent's implementation of this method as well.
2072 */
2073 void
readL2Attributes(const XMLAttributes & attributes)2074 UnitDefinition::readL2Attributes (const XMLAttributes& attributes)
2075 {
2076 const unsigned int level = getLevel();
2077 const unsigned int version = getVersion();
2078
2079 //
2080 // id: SId { use="required" } (L2v1, L2v2)
2081 //
2082 bool assigned;
2083 assigned = attributes.readInto("id", mId, getErrorLog(), true, getLine(), getColumn());
2084 if (assigned && mId.size() == 0)
2085 {
2086 logEmptyString("id", level, version, "<unitDefinition>");
2087 }
2088 if (!SyntaxChecker::isValidInternalSId(mId))
2089 logError(InvalidIdSyntax, level, version, "The id '" + mId + "' does not conform to the syntax.");
2090
2091 //
2092 // name: string { use="optional" } (L2v1->)
2093 //
2094 attributes.readInto("name", mName, getErrorLog(), false, getLine(), getColumn());
2095 }
2096 /** @endcond */
2097
2098
2099 /** @cond doxygenLibsbmlInternal */
2100 /*
2101 * Subclasses should override this method to read values from the given
2102 * XMLAttributes set into their specific fields. Be sure to call your
2103 * parent's implementation of this method as well.
2104 */
2105 void
readL3Attributes(const XMLAttributes & attributes)2106 UnitDefinition::readL3Attributes (const XMLAttributes& attributes)
2107 {
2108 const unsigned int level = getLevel();
2109 const unsigned int version = getVersion();
2110
2111 //
2112 // id: SId { use="required" } (L2v1, L2v2)
2113 //
2114 bool assigned;
2115 // for l3v2 sbase will read this as generically optional
2116 // we want to log errors relating to the specific object
2117 if (version == 1)
2118 {
2119 assigned = attributes.readInto("id", mId, getErrorLog(), false, getLine(), getColumn());
2120 if (!assigned)
2121 {
2122 logError(AllowedAttributesOnUnitDefinition, level, version,
2123 "The required attribute 'id' is missing.");
2124 }
2125 if (assigned && mId.size() == 0)
2126 {
2127 logEmptyString("id", level, version, "<unitDefinition>");
2128 }
2129 if (!SyntaxChecker::isValidInternalSId(mId))
2130 logError(InvalidIdSyntax, level, version, "The id '" + mId + "' does not conform to the syntax.");
2131 }
2132 else
2133 {
2134 // need to check that id was present
2135 // it has already been read and checked for syntax/emptyness
2136 if (attributes.hasAttribute("id") == false)
2137 {
2138 logError(AllowedAttributesOnUnitDefinition, level, version,
2139 "The required attribute 'id' is missing.");
2140 }
2141 }
2142
2143 //
2144 // name: string { use="optional" } (L2v1->)
2145 //
2146 // for l3v2 sbase will read this
2147 if (version == 1)
2148 {
2149 attributes.readInto("name", mName, getErrorLog(), false,
2150 getLine(), getColumn());
2151 }
2152 }
2153 /** @endcond */
2154
2155
2156 /** @cond doxygenLibsbmlInternal */
2157 /*
2158 * Subclasses should override this method to write their XML attributes
2159 * to the XMLOutputStream. Be sure to call your parent's implementation
2160 * of this method as well.
2161 */
2162 void
writeAttributes(XMLOutputStream & stream) const2163 UnitDefinition::writeAttributes (XMLOutputStream& stream) const
2164 {
2165 SBase::writeAttributes(stream);
2166
2167 const unsigned int level = getLevel();
2168 unsigned int version = getVersion();
2169
2170 // for L3V2 and above SBase will write this out
2171 if (level < 3 || (level == 3 && version == 1))
2172 {
2173 //
2174 // name: SName { use="required" } (L1v1, L1v2)
2175 // id: SId { use="required" } (L2v1, L2v2)
2176 //
2177 const string id = (level == 1) ? "name" : "id";
2178 stream.writeAttribute(id, mId);
2179 }
2180
2181 if (level > 1)
2182 {
2183 // for L3V2 and above SBase will write this out
2184 if (level < 3 || (level == 3 && version == 1))
2185 {
2186 //
2187 // name: string { use="optional" } (L2v1->)
2188 //
2189 stream.writeAttribute("name", mName);
2190 }
2191 }
2192
2193 //
2194 // sboTerm: SBOTerm { use="optional" } (L2v3->)
2195 // is written in SBase::writeAttributes()
2196 //
2197
2198 //
2199 // (EXTENSION)
2200 //
2201 SBase::writeExtensionAttributes(stream);
2202 }
2203 /** @endcond */
2204
2205
2206 /** @cond doxygenLibsbmlInternal */
2207 /*
2208 * Subclasses should override this method to write out their contained
2209 * SBML objects as XML elements. Be sure to call your parent's
2210 * implementation of this method as well.
2211 */
2212 void
writeElements(XMLOutputStream & stream) const2213 UnitDefinition::writeElements (XMLOutputStream& stream) const
2214 {
2215 SBase::writeElements(stream);
2216
2217 if (getLevel() == 3 && getVersion() > 1)
2218 {
2219 if (mUnits.hasOptionalElements() == true ||
2220 mUnits.hasOptionalAttributes() == true ||
2221 mUnits.isExplicitlyListed())
2222 {
2223 mUnits.write(stream);
2224 }
2225 }
2226 else
2227 {
2228 // use original code
2229 if ( getNumUnits() > 0 ) mUnits.write(stream);
2230 }
2231
2232 //
2233 // (EXTENSION)
2234 //
2235 SBase::writeExtensionElements(stream);
2236 }
2237 /** @endcond */
2238
2239
2240 /*
2241 * Creates a new ListOfUnitDefinitions items.
2242 */
ListOfUnitDefinitions(unsigned int level,unsigned int version)2243 ListOfUnitDefinitions::ListOfUnitDefinitions (unsigned int level, unsigned int version)
2244 : ListOf(level,version)
2245 {
2246 }
2247
2248
2249 /*
2250 * Creates a new ListOfUnitDefinitions items.
2251 */
ListOfUnitDefinitions(SBMLNamespaces * sbmlns)2252 ListOfUnitDefinitions::ListOfUnitDefinitions (SBMLNamespaces* sbmlns)
2253 : ListOf(sbmlns)
2254 {
2255 loadPlugins(sbmlns);
2256 }
2257
2258
2259 /*
2260 * @return a (deep) copy of this ListOfUnitDefinitions.
2261 */
2262 ListOfUnitDefinitions*
clone() const2263 ListOfUnitDefinitions::clone () const
2264 {
2265 return new ListOfUnitDefinitions(*this);
2266 }
2267
2268
2269 /*
2270 * @return the typecode (int) of SBML objects contained in this ListOf or
2271 * SBML_UNKNOWN (default).
2272 */
2273 int
getItemTypeCode() const2274 ListOfUnitDefinitions::getItemTypeCode () const
2275 {
2276 return SBML_UNIT_DEFINITION;
2277 }
2278
2279
2280 /*
2281 * @return the name of this element ie "listOfUnitDefinitions".
2282 */
2283 const string&
getElementName() const2284 ListOfUnitDefinitions::getElementName () const
2285 {
2286 static const string name = "listOfUnitDefinitions";
2287 return name;
2288 }
2289
2290
2291 /* return nth item in list */
2292 UnitDefinition *
get(unsigned int n)2293 ListOfUnitDefinitions::get(unsigned int n)
2294 {
2295 return static_cast<UnitDefinition*>(ListOf::get(n));
2296 }
2297
2298
2299 /* return nth item in list */
2300 const UnitDefinition *
get(unsigned int n) const2301 ListOfUnitDefinitions::get(unsigned int n) const
2302 {
2303 return static_cast<const UnitDefinition*>(ListOf::get(n));
2304 }
2305
2306
2307 /**
2308 * Used by ListOf::get() to lookup an SBase based by its id.
2309 */
2310 struct IdEqUD : public unary_function<SBase*, bool>
2311 {
2312 const string& mId;
2313
IdEqUDIdEqUD2314 IdEqUD (const string& id) : mId(id) { }
operator ()IdEqUD2315 bool operator() (SBase* sb)
2316 { return static_cast <UnitDefinition *> (sb)->getId() == mId; }
2317 };
2318
2319
2320 /* return item by id */
2321 UnitDefinition*
get(const std::string & sid)2322 ListOfUnitDefinitions::get (const std::string& sid)
2323 {
2324 return const_cast<UnitDefinition*>(
2325 static_cast<const ListOfUnitDefinitions&>(*this).get(sid) );
2326 }
2327
2328
2329 /* return item by id */
2330 const UnitDefinition*
get(const std::string & sid) const2331 ListOfUnitDefinitions::get (const std::string& sid) const
2332 {
2333 vector<SBase*>::const_iterator result;
2334
2335 result = find_if( mItems.begin(), mItems.end(), IdEqUD(sid) );
2336 return (result == mItems.end()) ? NULL :
2337 static_cast <UnitDefinition*> (*result);
2338 }
2339
2340
2341 SBase*
getElementBySId(const std::string & id)2342 ListOfUnitDefinitions::getElementBySId(const std::string& id)
2343 {
2344 for (unsigned int i = 0; i < size(); i++)
2345 {
2346 SBase* obj = get(i);
2347 //Units are not in the SId namespace, so don't check 'getId'. However, their children (through plugins) may have the element we are looking for, so we still need to check all of them.
2348 obj = obj->getElementBySId(id);
2349 if (obj != NULL) return obj;
2350 }
2351
2352 return getElementFromPluginsBySId(id);
2353 }
2354
2355 /* Removes the nth item from this list */
2356 UnitDefinition*
remove(unsigned int n)2357 ListOfUnitDefinitions::remove (unsigned int n)
2358 {
2359 return static_cast<UnitDefinition*>(ListOf::remove(n));
2360 }
2361
2362
2363 /* Removes item in this list by id */
2364 UnitDefinition*
remove(const std::string & sid)2365 ListOfUnitDefinitions::remove (const std::string& sid)
2366 {
2367 SBase* item = NULL;
2368 ListItemIter result;
2369
2370 result = find_if( mItems.begin(), mItems.end(), IdEqUD(sid) );
2371
2372 if (result != mItems.end())
2373 {
2374 item = *result;
2375 mItems.erase(result);
2376 }
2377
2378 return static_cast <UnitDefinition*> (item);
2379 }
2380
2381
2382 /** @cond doxygenLibsbmlInternal */
2383 /*
2384 * @return the ordinal position of the element with respect to its siblings
2385 * or -1 (default) to indicate the position is not significant.
2386 */
2387 int
getElementPosition() const2388 ListOfUnitDefinitions::getElementPosition () const
2389 {
2390 return 2;
2391 }
2392 /** @endcond */
2393
2394
2395 /** @cond doxygenLibsbmlInternal */
2396 /*
2397 * @return the SBML object corresponding to next XMLToken in the
2398 * XMLInputStream or @c NULL if the token was not recognized.
2399 */
2400 SBase*
createObject(XMLInputStream & stream)2401 ListOfUnitDefinitions::createObject (XMLInputStream& stream)
2402 {
2403 const string& name = stream.peek().getName();
2404 SBase* object = NULL;
2405
2406
2407 if (name == "unitDefinition")
2408 {
2409 try
2410 {
2411 object = new UnitDefinition(getSBMLNamespaces());
2412 }
2413 catch (SBMLConstructorException*)
2414 {
2415 object = new UnitDefinition(SBMLDocument::getDefaultLevel(),
2416 SBMLDocument::getDefaultVersion());
2417 }
2418 catch ( ... )
2419 {
2420 object = new UnitDefinition(SBMLDocument::getDefaultLevel(),
2421 SBMLDocument::getDefaultVersion());
2422 }
2423
2424 if (object != NULL) mItems.push_back(object);
2425 }
2426
2427 return object;
2428 }
2429 /** @endcond */
2430
2431
2432 #endif /* __cplusplus */
2433 /** @cond doxygenIgnored */
2434 LIBSBML_EXTERN
2435 UnitDefinition_t *
UnitDefinition_create(unsigned int level,unsigned int version)2436 UnitDefinition_create (unsigned int level, unsigned int version)
2437 {
2438 try
2439 {
2440 UnitDefinition* obj = new UnitDefinition(level,version);
2441 return obj;
2442 }
2443 catch (SBMLConstructorException)
2444 {
2445 return NULL;
2446 }
2447 }
2448
2449
2450 LIBSBML_EXTERN
2451 UnitDefinition_t *
UnitDefinition_createWithNS(SBMLNamespaces_t * sbmlns)2452 UnitDefinition_createWithNS (SBMLNamespaces_t* sbmlns)
2453 {
2454 try
2455 {
2456 UnitDefinition* obj = new UnitDefinition(sbmlns);
2457 return obj;
2458 }
2459 catch (SBMLConstructorException)
2460 {
2461 return NULL;
2462 }
2463 }
2464
2465
2466 LIBSBML_EXTERN
2467 void
UnitDefinition_free(UnitDefinition_t * ud)2468 UnitDefinition_free (UnitDefinition_t *ud)
2469 {
2470 delete ud;
2471 }
2472
2473
2474 LIBSBML_EXTERN
2475 UnitDefinition_t*
UnitDefinition_clone(const UnitDefinition_t * ud)2476 UnitDefinition_clone (const UnitDefinition_t *ud)
2477 {
2478 return (ud != NULL) ? static_cast<UnitDefinition_t*>( ud->clone() ) : NULL;
2479 }
2480
2481
2482 LIBSBML_EXTERN
2483 const XMLNamespaces_t *
UnitDefinition_getNamespaces(UnitDefinition_t * ud)2484 UnitDefinition_getNamespaces(UnitDefinition_t *ud)
2485 {
2486 return (ud != NULL) ? ud->getNamespaces() : NULL;
2487 }
2488
2489 LIBSBML_EXTERN
2490 const char *
UnitDefinition_getId(const UnitDefinition_t * ud)2491 UnitDefinition_getId (const UnitDefinition_t *ud)
2492 {
2493 return (ud != NULL && ud->isSetId()) ? ud->getId().c_str() : NULL;
2494 }
2495
2496
2497 LIBSBML_EXTERN
2498 const char *
UnitDefinition_getName(const UnitDefinition_t * ud)2499 UnitDefinition_getName (const UnitDefinition_t *ud)
2500 {
2501 return (ud != NULL && ud->isSetName()) ? ud->getName().c_str() : NULL;
2502 }
2503
2504
2505 LIBSBML_EXTERN
2506 int
UnitDefinition_isSetId(const UnitDefinition_t * ud)2507 UnitDefinition_isSetId (const UnitDefinition_t *ud)
2508 {
2509 return (ud != NULL) ? static_cast<int>( ud->isSetId() ) : 0;
2510 }
2511
2512
2513 LIBSBML_EXTERN
2514 int
UnitDefinition_isSetName(const UnitDefinition_t * ud)2515 UnitDefinition_isSetName (const UnitDefinition_t *ud)
2516 {
2517 return (ud != NULL) ? static_cast<int>( ud->isSetName() ) : 0;
2518 }
2519
2520
2521 LIBSBML_EXTERN
2522 int
UnitDefinition_isVariantOfArea(const UnitDefinition_t * ud)2523 UnitDefinition_isVariantOfArea (const UnitDefinition_t *ud)
2524 {
2525 return (ud != NULL) ? static_cast<int>( ud->isVariantOfArea() ) : 0;
2526 }
2527
2528
2529 LIBSBML_EXTERN
2530 int
UnitDefinition_isVariantOfLength(const UnitDefinition_t * ud)2531 UnitDefinition_isVariantOfLength (const UnitDefinition_t *ud)
2532 {
2533 return (ud != NULL) ? static_cast<int>( ud->isVariantOfLength() ) : 0;
2534 }
2535
2536
2537 LIBSBML_EXTERN
2538 int
UnitDefinition_isVariantOfSubstance(const UnitDefinition_t * ud)2539 UnitDefinition_isVariantOfSubstance (const UnitDefinition_t *ud)
2540 {
2541 return (ud != NULL) ? static_cast<int>( ud->isVariantOfSubstance() ) : 0;
2542 }
2543
2544
2545 LIBSBML_EXTERN
2546 int
UnitDefinition_isVariantOfTime(const UnitDefinition_t * ud)2547 UnitDefinition_isVariantOfTime (const UnitDefinition_t *ud)
2548 {
2549 return (ud != NULL) ? static_cast<int>( ud->isVariantOfTime() ) : 0;
2550 }
2551
2552
2553 LIBSBML_EXTERN
2554 int
UnitDefinition_isVariantOfVolume(const UnitDefinition_t * ud)2555 UnitDefinition_isVariantOfVolume (const UnitDefinition_t *ud)
2556 {
2557 return (ud != NULL) ? static_cast<int>( ud->isVariantOfVolume() ) : 0;
2558 }
2559
2560
2561 LIBSBML_EXTERN
2562 int
UnitDefinition_isVariantOfDimensionless(const UnitDefinition_t * ud)2563 UnitDefinition_isVariantOfDimensionless (const UnitDefinition_t *ud)
2564 {
2565 return (ud != NULL) ? static_cast<int>( ud->isVariantOfDimensionless() ) : 0;
2566 }
2567
2568
2569 LIBSBML_EXTERN
2570 int
UnitDefinition_isVariantOfMass(const UnitDefinition_t * ud)2571 UnitDefinition_isVariantOfMass (const UnitDefinition_t *ud)
2572 {
2573 return (ud != NULL) ? static_cast<int>( ud->isVariantOfMass() ) : 0;
2574 }
2575
2576
2577 LIBSBML_EXTERN
2578 int
UnitDefinition_isVariantOfSubstancePerTime(const UnitDefinition_t * ud)2579 UnitDefinition_isVariantOfSubstancePerTime (const UnitDefinition_t *ud)
2580 {
2581 return (ud != NULL) ?
2582 static_cast<int>( ud->isVariantOfSubstancePerTime() ) : 0;
2583 }
2584
2585
2586 LIBSBML_EXTERN
2587 int
UnitDefinition_setId(UnitDefinition_t * ud,const char * id)2588 UnitDefinition_setId (UnitDefinition_t *ud, const char *id)
2589 {
2590 if (ud != NULL)
2591 return (id == NULL) ? ud->setId("") : ud->setId(id);
2592 else
2593 return LIBSBML_INVALID_OBJECT;
2594 }
2595
2596
2597 LIBSBML_EXTERN
2598 int
UnitDefinition_setName(UnitDefinition_t * ud,const char * name)2599 UnitDefinition_setName (UnitDefinition_t *ud, const char *name)
2600 {
2601 if (ud != NULL)
2602 return (name == NULL) ? ud->unsetName() : ud->setName(name);
2603 else
2604 return LIBSBML_INVALID_OBJECT;
2605 }
2606
2607
2608 LIBSBML_EXTERN
2609 int
UnitDefinition_unsetName(UnitDefinition_t * ud)2610 UnitDefinition_unsetName (UnitDefinition_t *ud)
2611 {
2612 return (ud != NULL) ? ud->unsetName() : LIBSBML_INVALID_OBJECT;
2613 }
2614
2615
2616 LIBSBML_EXTERN
2617 int
UnitDefinition_addUnit(UnitDefinition_t * ud,const Unit_t * u)2618 UnitDefinition_addUnit (UnitDefinition_t *ud, const Unit_t *u)
2619 {
2620 return (ud != NULL) ? ud->addUnit(u) : LIBSBML_INVALID_OBJECT;
2621 }
2622
2623
2624 LIBSBML_EXTERN
2625 Unit_t *
UnitDefinition_createUnit(UnitDefinition_t * ud)2626 UnitDefinition_createUnit (UnitDefinition_t *ud)
2627 {
2628 return (ud != NULL) ? ud->createUnit() : NULL;
2629 }
2630
2631
2632 LIBSBML_EXTERN
2633 ListOf_t *
UnitDefinition_getListOfUnits(UnitDefinition_t * ud)2634 UnitDefinition_getListOfUnits (UnitDefinition_t *ud)
2635 {
2636 return (ud != NULL) ? ud->getListOfUnits() : NULL;
2637 }
2638
2639
2640 LIBSBML_EXTERN
2641 Unit_t *
UnitDefinition_getUnit(UnitDefinition_t * ud,unsigned int n)2642 UnitDefinition_getUnit (UnitDefinition_t *ud, unsigned int n)
2643 {
2644 return (ud != NULL) ? ud->getUnit(n) : NULL;
2645 }
2646
2647
2648 LIBSBML_EXTERN
2649 Unit_t *
UnitDefinition_removeUnit(UnitDefinition_t * ud,unsigned int n)2650 UnitDefinition_removeUnit (UnitDefinition_t *ud, unsigned int n)
2651 {
2652 if (ud != NULL)
2653 return ud->removeUnit(n);
2654 else
2655 return NULL;
2656 }
2657
2658
2659 LIBSBML_EXTERN
2660 unsigned int
UnitDefinition_getNumUnits(const UnitDefinition_t * ud)2661 UnitDefinition_getNumUnits (const UnitDefinition_t *ud)
2662 {
2663 return (ud != NULL) ? ud->getNumUnits() : SBML_INT_MAX;
2664 }
2665
2666
2667 LIBSBML_EXTERN
2668 void
UnitDefinition_simplify(UnitDefinition_t * ud)2669 UnitDefinition_simplify(UnitDefinition_t * ud)
2670 {
2671 if (ud != NULL)
2672 UnitDefinition::simplify(static_cast<UnitDefinition*>(ud));
2673 }
2674
2675 LIBSBML_EXTERN
2676 void
UnitDefinition_reorder(UnitDefinition_t * ud)2677 UnitDefinition_reorder(UnitDefinition_t * ud)
2678 {
2679 if (ud != NULL)
2680 UnitDefinition::reorder(static_cast<UnitDefinition*>(ud));
2681 }
2682
2683 LIBSBML_EXTERN
2684 UnitDefinition_t *
UnitDefinition_convertToSI(UnitDefinition_t * ud)2685 UnitDefinition_convertToSI(UnitDefinition_t * ud)
2686 {
2687 return (ud != NULL) ?
2688 UnitDefinition::convertToSI(static_cast<UnitDefinition*>(ud)) : NULL;
2689 }
2690
2691 LIBSBML_EXTERN
2692 int
UnitDefinition_areIdentical(UnitDefinition_t * ud1,UnitDefinition_t * ud2)2693 UnitDefinition_areIdentical(UnitDefinition_t * ud1, UnitDefinition_t * ud2)
2694 {
2695 if (ud1 != NULL && ud2 != NULL)
2696 return static_cast<int>
2697 (UnitDefinition::areIdentical(static_cast<UnitDefinition*>(ud1),
2698 static_cast<UnitDefinition*>(ud2)));
2699 else
2700 return 0;
2701 }
2702
2703 LIBSBML_EXTERN
2704 int
UnitDefinition_areEquivalent(UnitDefinition_t * ud1,UnitDefinition_t * ud2)2705 UnitDefinition_areEquivalent(UnitDefinition_t *ud1 , UnitDefinition_t * ud2)
2706 {
2707 if (ud1 != NULL && ud2 != NULL)
2708 return static_cast<int>(
2709 UnitDefinition::areEquivalent(static_cast<UnitDefinition*>(ud1),
2710 static_cast<UnitDefinition*>(ud2)));
2711 else
2712 return 0;
2713 }
2714
2715 LIBSBML_EXTERN
2716 UnitDefinition_t *
UnitDefinition_combine(UnitDefinition_t * ud1,UnitDefinition_t * ud2)2717 UnitDefinition_combine(UnitDefinition_t * ud1, UnitDefinition_t * ud2)
2718 {
2719 return UnitDefinition::combine(static_cast<UnitDefinition*>(ud1),
2720 static_cast<UnitDefinition*>(ud2));
2721 }
2722
2723
2724 LIBSBML_EXTERN
2725 UnitDefinition_t *
UnitDefinition_divide(UnitDefinition_t * ud1,UnitDefinition_t * ud2)2726 UnitDefinition_divide(UnitDefinition_t * ud1, UnitDefinition_t * ud2)
2727 {
2728 return UnitDefinition::divide(static_cast<UnitDefinition*>(ud1),
2729 static_cast<UnitDefinition*>(ud2));
2730 }
2731
2732
2733 LIBSBML_EXTERN
2734 char *
UnitDefinition_printUnits(UnitDefinition_t * ud,int compact)2735 UnitDefinition_printUnits(UnitDefinition_t * ud, int compact)
2736 {
2737 return (ud != NULL) ?
2738 safe_strdup(UnitDefinition::printUnits(static_cast<UnitDefinition*>(ud)
2739 , compact).c_str()) : NULL;
2740 }
2741
2742 LIBSBML_EXTERN
2743 UnitDefinition_t *
ListOfUnitDefinitions_getById(ListOf_t * lo,const char * sid)2744 ListOfUnitDefinitions_getById (ListOf_t *lo, const char *sid)
2745 {
2746 if (lo != NULL)
2747 return (sid != NULL) ?
2748 static_cast <ListOfUnitDefinitions *> (lo)->get(sid) : NULL;
2749 else
2750 return NULL;
2751 }
2752
2753
2754 LIBSBML_EXTERN
2755 UnitDefinition_t *
ListOfUnitDefinitions_removeById(ListOf_t * lo,const char * sid)2756 ListOfUnitDefinitions_removeById (ListOf_t *lo, const char *sid)
2757 {
2758 if (lo != NULL)
2759 return (sid != NULL) ?
2760 static_cast <ListOfUnitDefinitions *> (lo)->remove(sid) : NULL;
2761 else
2762 return NULL;
2763 }
2764 /** @endcond */
2765
2766 LIBSBML_CPP_NAMESPACE_END
2767
2768