C:/nobackup/private/physical_svn/trunk/include/physical/dimension.hpp

Go to the documentation of this file.
00001 
00002 /*=============================================================================
00003     physical quantities / units / constants
00004     Copyright (c) 2006, 2007 Martin Schulz
00005     http://physical.sourceforge.net
00006   
00007     This is private code by Martin Schulz.
00008   
00009     Use, modification and distribution is subject to the Boost Software
00010     License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
00011     http://www.boost.org/LICENSE_1_0.txt)
00012 =============================================================================*/
00013 
00014 #ifndef PHYSICAL_DIMENSION
00015 #define PHYSICAL_DIMENSION
00016 
00017 #include "physical/fixedphysical.hpp"
00018 #include "physical/dynamicphysical.hpp"
00019 #include "physical/formatspec.hpp"
00020 
00021 
00022 namespace physical {
00023 
00024         namespace format {
00025 
00026                 template<class T>
00027                 struct type2type {
00028                         typedef T type;
00029                 };
00030 
00031                 // a dimension is a collection of compatible FormatSpecs:
00032                 // FIXME: Needs further discussion
00033                 //
00034                 // i18n: The name of the dimension should only be an internal name (e.g. some english string). 
00035                 // The translation to other languages should be done by the calling method or class.
00036                 class Dimension {
00037                 public:
00038                         typedef physical::detail::DynamicExponents<SI> exponents_type;
00039 
00040                         Dimension(std::string name, const exponents_type& e)
00041                                 : dimensionname(name), exponents_(e) {};
00042 
00043                         /* How to use that one? 
00044                                 The definition looks promising and is accepted by the compiler, but how can 
00045                                 I actually make use of this templated constructor of an non-template class?
00046                         template<class Quantity>
00047                         Dimension(std::string name)
00048                                 : dimensionname(name), exponents_(Quantity::exponents()) {};
00049                         */
00050 
00051                         /* This templated constructor reqires the instantiation of a quantity 
00052                                 only in order to transport its type. This is nevertheless quite handy 
00053                                 if you already have a FixedPhysical of that kind on hand, e.g. some 
00054                                 unit in the unit namespace.
00055                                 */
00056                         template<typename T, class Exponents>
00057                         Dimension(std::string name, const FixedPhysical<SI, T, Exponents>&)
00058                                 : dimensionname(name), exponents_(Exponents()) {};
00059 
00060                         /* This one is more tricky: 
00061                                 I use type2type here in order to create a lightweight instance
00062                                 of type2type instead of more heavyweight quantity.
00063                         */
00064                         template<class Quantity>
00065                         Dimension(std::string name, const type2type<Quantity>&)
00066                                 : dimensionname(name), exponents_(typename Quantity::exponents()) {};
00067 
00068                         Dimension(std::string name, const DynamicPhysical<SI>& q)
00069                                 : dimensionname(name), exponents_(q.exponents) {};
00070 
00071                         // copy constructor and automatic assignement operator are ok.
00072 
00073                         std::string name() const {return dimensionname;};
00074                                 
00075                         // the set of exponents, to which any formatspec to add must be compatible to.
00076                         exponents_type exponents() const { return exponents_;};
00077 
00078                         Dimension& add(const FormatSpec<SI>& s) {
00079                                 if ( s.unit.exponents == exponents()) {
00080                                         specs.push_back(s);
00081                                 } else {
00082                                         throw IncompatibleUnitException("addition of incompatible formatspec");
00083                                 };
00084                                 return *this;
00085                         };
00086 
00087                         // FIXME: swap() ? 
00088                         // FIXME: clear() ? 
00089 
00090                         // the favourite does not belong here. The mapping of Dimensions to favourites 
00091                         // should be managed by some other entity. 
00092                         FormatSpec<SI> favourite() const {return specs[0];};
00093 
00094                         // ouah, I dislike that one. But we will need some method to iterate over all FormatSpecs, 
00095                         // e.g. if we want to set up a dropdown list of available FormatSpecs the user could choose from.
00096                         // Better provide iterators: begin(), end() 
00097                         FormatSpec<SI> get(std::size_t i) const {
00098                                 if ( 0<=i && i<specs.size() ) {
00099                                         return specs[0]; 
00100                                 } else {
00101                                         throw std::range_error("Dimension: cannot find spec");
00102                                 };
00103                         }
00104 
00105                 private:
00106 
00107                         // Exponents to be used to check for compatibility .
00108                         // immutable after construction, only by assignment 
00109                         exponents_type exponents_; 
00110                         
00111                         // immutable after construction, only by assignment
00112                         std::string dimensionname;
00113 
00114                         std::vector<FormatSpec<SI> > specs;
00115                 };
00116 
00117 
00118                 template<class Quantity>
00119                 struct DimensionDef: public Dimension {
00120                         DimensionDef(std::string name): Dimension(name, type2type<Quantity>()){};
00121                 };
00122 
00123         }; // namespace format
00124 
00125 }; // namespace physical
00126 
00127 
00128 #endif

Generated on Mon Apr 2 22:25:03 2007 for physical_svn by  doxygen 1.5.1-p1
hosted on SourceForge.net Logo