From 4ab0ccaf6d420abf5f6a821601f5e0d399859aff Mon Sep 17 00:00:00 2001 From: Aleksandar Fabijanic Date: Thu, 14 Aug 2008 10:04:46 +0000 Subject: [PATCH] Units --- Util/Util_vs71.vcproj | 4 + Util/Util_vs80.vcproj | 4 + Util/Util_vs90.vcproj | 4 + Util/include/Poco/Util/Units.h | 1288 ++++++++++++++++++++++++++ Util/samples/Makefile | 1 + Util/samples/Units/Makefile | 17 + Util/samples/Units/Units_vs71.vcproj | 267 ++++++ Util/samples/Units/Units_vs80.vcproj | 390 ++++++++ Util/samples/Units/Units_vs90.vcproj | 379 ++++++++ Util/samples/Units/src/Units.cpp | 121 +++ Util/samples/samples_vs80.sln | 10 + 11 files changed, 2485 insertions(+) create mode 100644 Util/include/Poco/Util/Units.h create mode 100644 Util/samples/Units/Makefile create mode 100644 Util/samples/Units/Units_vs71.vcproj create mode 100644 Util/samples/Units/Units_vs80.vcproj create mode 100644 Util/samples/Units/Units_vs90.vcproj create mode 100644 Util/samples/Units/src/Units.cpp diff --git a/Util/Util_vs71.vcproj b/Util/Util_vs71.vcproj index 1606ea609..dad1d01c1 100644 --- a/Util/Util_vs71.vcproj +++ b/Util/Util_vs71.vcproj @@ -459,6 +459,10 @@ + + + diff --git a/Util/Util_vs80.vcproj b/Util/Util_vs80.vcproj index d63a9c2c1..455b734d5 100644 --- a/Util/Util_vs80.vcproj +++ b/Util/Util_vs80.vcproj @@ -623,6 +623,10 @@ + + diff --git a/Util/Util_vs90.vcproj b/Util/Util_vs90.vcproj index 9c6e9ad42..fe3438ae5 100644 --- a/Util/Util_vs90.vcproj +++ b/Util/Util_vs90.vcproj @@ -612,6 +612,10 @@ + + diff --git a/Util/include/Poco/Util/Units.h b/Util/include/Poco/Util/Units.h new file mode 100644 index 000000000..7d731cb2f --- /dev/null +++ b/Util/include/Poco/Util/Units.h @@ -0,0 +1,1288 @@ +// +// Units.h +// +// $Id: //poco/svn/Util/include/Poco/Util/Units.h#1 $ +// +// Library: Util +// Package: Util +// Module: Units +// +// Basic definitions for the Poco Util library. +// This file must be the first file included by every other Util +// header file. +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + +// +// Adapted for POCO from the following source: +// +// Written by Calum Grant +// Copyright (C) Calum Grant 2007 +// +// Home page: http://calumgrant.net/units +// File location: http://calumgrant.net/units/Units.hpp +// +// Copying permitted under the terms of the Boost software license. +// + + +#ifndef Util_Units_INCLUDED +#define Util_Units_INCLUDED + + +#include +#include + + +namespace Poco { +namespace Util { +namespace Units { + + namespace Internal + { + template struct Convert; + /// Forward + + struct None; + /// Allows construction of no units + + template + struct FixedPower; + /// Forward + } + + + template + struct Compose; + /// Construct a unit equivalent to Unit1*Unit2 + + template + struct Scale; + /// Constructs a unit equivalent to U*Num/Den + + template + struct Translate; + /// Constructs a Unit equivalent to U+Num/Den + + template + struct Power; + /// Constructs a Unit equivalent to U^(Num/Den) + + typedef Power Unit; + /// A unit which is effectively no units at all. + + template + class Value + /// A Value with a unit. + /// V is the type you are storing + /// U is the units of the Value + { + public: + typedef V ValueType; + typedef U Unit; + + Value() : _rep() + { + } + + explicit Value(const ValueType & v) : _rep(v) + { + } + + template + Value(const Value & v) : + _rep(Internal::Convert::fn(v.get())) + { + } + + const ValueType & get() const + { + return _rep; + } + + template + Value & operator=(const Value & other) + { + _rep = Value(other).get(); + return *this; + } + + template + Value operator+(const Value & other) const + { + return Value(get() + Value(other).get()); + } + + template + Value &operator+=(const Value & other) + { + _rep += Value(other).get(); + return *this; + } + + template + Value &operator-=(const Value & other) + { + _rep -= Value(other).get(); + return *this; + } + + template + Value operator-(const Value & other) const + { + return Value(get() - Value(other).get()); + } + + Value operator-() const + { + return Value(-get()); + } + + template + Value< V, Compose > + operator*(const Value & other) const + { + return Value >(get() * other.get()); + } + + Value operator*(const ValueType & v) const + { + return Value(get() * v); + } + + Value & operator*=(const ValueType & v) + { + _rep *= v; + return *this; + } + + template + Value< V, Compose > > + operator/(const Value & other) const + { + return Value > >(get() / other.get()); + } + + Value operator/(const ValueType & v) const + { + return Value(get() / v); + } + + Value & operator/=(const ValueType & v) + { + _rep /= v; + return *this; + } + + template + bool operator==(const Value & other) const + { + return get() == Value(other).get(); + } + + template + bool operator!=(const Value & other) const + { + return get() != Value(other).get(); + } + + template + bool operator<(const Value & other) const + { + return get() < Value(other).get(); + } + + template + bool operator<=(const Value & other) const + { + return get() <= Value(other).get(); + } + + template + bool operator>(const Value & other) const + { + return get() > Value(other).get(); + } + + template + bool operator>=(const Value & other) const + { + return get() >= Value(other).get(); + } + + Value & operator++() + { + ++_rep; + return *this; + } + + Value operator++(int) + { + Value v = *this; + ++_rep; + return v; + } + + Value & operator--() + { + --_rep; + return *this; + } + + Value operator--(int) + { + Value v = *this; + --_rep; + return v; + } + + private: + ValueType _rep; + }; + + + template + Value > operator/(const V & a, const Value & b) + { + return Value >(a / b.get()); + } + + + template + Value operator*(const V & a, const Value & b) + { + return Value(a * b.get()); + } + + + template + Value > sqrt(const Value & a) + { + return Value >(std::sqrt(a.get())); + } + + + template + Value > square(const Value & a) + { + return Value >(std::pow(a.get(), 2)); + } + + + template + Value > cube(const Value & a) + { + return Value >(std::pow(a.get(), 3)); + } + + + template + Value > raise(const Value & a) + { + return Value >(Internal::FixedPower::Power(a.get())); + } + +} + + +// +// Implementation +// + +namespace Units +{ + namespace Internal + { + template struct static_assert; + template<> struct static_assert { }; + /// Ensures (at compile-time) that the template argument is true. + + template + struct Convertible; + /// Forward + + template + struct ScalingFactor; + /// Forward + + template + struct Convert3 + /// Converts T1 to T2. + /// Stage 3 - performed after Stage 1 and Stage 2. + /// The reason we perform Convert in stages is so that the compiler + /// can resolve templates in the order we want it to. + { + template + static V fn(const V & v) + /// The default implementation assumes that the two quantities are in compatible + /// Units up to some scaling factor. Find the scaling factor and apply it. + { + return v * ScalingFactor::template fn() / ScalingFactor::template fn(); + } + }; + + template + struct Convert2 + /// Converts T1 to T2. + /// Template matches the first argument (T1), + /// this is the fall-through to Convert3. + { + template + static V fn(const V & v) + { + return Convert3::fn(v); + } + }; + + template + struct Convert + /// Converts T1 to T2. + /// If you really want to implement your own conversion routine, + /// specialise this template. + /// The default implementation falls through to Convert2. + { + static_assert::Value> check_convertible; + /// If this fails, then T1 is not Convertible to T2: + + template + static V fn(const V & v) + { + return Convert2::fn(v); + } + }; + + template + struct Convert + /// Trivial conversion to the same type. + { + template + static const U & fn(const U & u) { return u; } + }; + + template + struct Convert3 + /// Convert to same type. + { + template + static const U & fn(const U & u) { return u; } + }; + + template + struct Convert2, U> + /// Convert from a scaled Unit + { + template + static V fn(const V & v) + { + return Convert::fn((v * Den)/Num); + } + }; + + template + struct Convert3 > + /// Convert to a scaled Unit + { + template + static V fn(const V & v) + { + return (Convert::fn(v) * Num)/ Den; + } + }; + + template + struct Convert2, U> + /// Convert from a translated Unit + { + template + static V fn(const V & v) + { + return Convert::fn(v - static_cast(Num) / static_cast(Den)); + } + }; + + template + struct Convert3 > + /// Convert to a translated Unit + { + template + static V fn(const V & v) + { + return Convert::fn(v) + static_cast(Num) / static_cast(Den); + } + }; + + template + struct CountTerms + /// Count the power to which Unit Term is raised in the Unit List. + /// Returns a rational num/den of the power of term Term in List. + /// The default assumes that Term is not found (num/den=0) + { + static const int num = 0; + static const int den = 1; + }; + + template + struct CountTerms + { + static const int num = 1; + static const int den = 1; + }; + + template + struct CountTerms > + /// CountTerms ignores scaling factors - that is taken care of by ScalingFactor. + { + typedef CountTerms result; + static const int num = result::num; + static const int den = result::den; + }; + + + template + struct CountTerms > + /// CountTerms ignores translation. + { + typedef CountTerms result; + static const int num = result::num; + static const int den = result::den; + }; + + template + struct CountTerms > + /// Addition of fractions. + { + typedef CountTerms result1; + typedef CountTerms result2; + static const int num = + result1::num * result2::den + result1::den * result2::num; + static const int den = + result1::den * result2::den; + }; + + template + struct CountTerms > + /// Multiplication of fractions. + { + typedef CountTerms result; + static const int num = N * result::num; + static const int den = D * result::den; + }; + + template + struct CheckTermsEqual + /// Counts the power of the Unit Term in Units T1 and T2. + /// Reports if they are equal, using equality of fractions. + /// Does a depth-first search of the Unit "Term", + /// or counts the terms in the default case. + { + typedef CountTerms count1; + typedef CountTerms count2; + + static const bool Value = + count1::num * count2::den == + count1::den * count2::num; + }; + + template + struct CheckTermsEqual, T1, T2 > + { + static const bool Value = CheckTermsEqual::Value; + }; + + template + struct CheckTermsEqual, T1, T2 > + { + static const bool Value = CheckTermsEqual::Value; + }; + + template + struct CheckTermsEqual, T1, T2 > + { + static const bool Value = CheckTermsEqual::Value; + }; + + template + struct CheckTermsEqual,T3,T4> + { + static const bool Value = + CheckTermsEqual::Value && + CheckTermsEqual::Value; + }; + + template + struct Convertible + /// Determines whether two types are Convertible + /// Counts the powers in the LHS and RHS and ensures they are equal. + { + static const bool Value = + CheckTermsEqual::Value && + CheckTermsEqual::Value; + }; + + template + struct FixedPower + /// A functor that raises a Value to the power Num/Den. + /// The template is specialised for efficiency + /// so that we don't always have to call the std::Power function. + { + template static T Power(const T & t) + { + return std::pow(t, static_cast(Num)/static_cast(Den)); + } + }; + + + template + struct FixedPower + { + template static const T & Power(const T & t) + { + return t; + } + }; + + + template + struct FixedPower + { + template static T Power(const T & t) + { + return t*t; + } + }; + + + template + struct FixedPower + { + template static T Power(const T & t) + { + return t*t*t; + } + }; + + + template + struct FixedPower + { + template static const T & Power(const T & t) + { + T u = t*t; + return u*u; + } + }; + + + template + struct FixedPower + { + template static T Power(const T & t) + { + return 1/t; + } + }; + + + template + struct FixedPower + { + template static T Power(const T & t) + { + return 1/(t*t); + } + }; + + + template + struct FixedPower + { + template static T Power(const T & t) + { + return 1; + } + }; + + template + struct ScalingFactor + /// Determine the scaling factor of a Unit in relation to its "base" Units. + /// Default is that U is a primitive Unit and is not scaled. + { + template + static T fn() { return 1; } + }; + + template + struct ScalingFactor< Compose > + { + template + static T fn() + { + return + ScalingFactor::template fn() * + ScalingFactor::template fn(); + } + }; + + template + struct ScalingFactor< Scale > + { + template + static T fn() + { + return + ScalingFactor::template fn() * + static_cast(N) / static_cast(D); + } + }; + + template + struct ScalingFactor< Power > + { + template + static T fn() + { + return FixedPower::Power(ScalingFactor::template fn()); + } + }; + + + template + struct ScalingFactor< Translate > + { + template + static T fn() + { + return ScalingFactor::template fn(); + } + }; + } +} + + +/// +/// Display +/// + +#define UNIT_DISPLAY_NAME(Unit, string) \ + template<> struct OutputUnit { \ + template static void fn(Stream& os) { os << string; } \ + }; + + +#define UNITS_DISPLAY_NAME(Unit, string) \ + namespace Units { UNIT_DISPLAY_NAME(Unit, string) } + + +namespace Units +{ + namespace Internal + { + template + struct OutputUnit2 + /// The default Unit formatting mechanism + { + template + static void fn(Stream &os) { os << "Units"; } + }; + } + + template + struct OutputUnit + /// Functor to write Unit text to stream + { + template + static void fn(Stream &os) { Internal::OutputUnit2::fn(os); } + }; + + + UNIT_DISPLAY_NAME(Unit, "1"); + + + namespace Internal + { + template + struct OutputUnit2< Compose > + { + template + static void fn(Stream &os) + { + OutputUnit::fn(os); + os << '.'; + OutputUnit::fn(os); + } + }; + + + template + struct OutputUnit2< Power > + { + template + static void fn(Stream &os) + { + if(Num!=Den) os << '('; + OutputUnit::fn(os); + if(Num!=Den) + { + os << ')'; + os << '^' << Num; + if(Num%Den) + { + os << '/' << Den; + } + } + } + }; + + + template + struct OutputUnit2< Translate > + { + template + static void fn(Stream &os) + { + os << '('; + OutputUnit::fn(os); + os << '+' << Num; + if(Den!=1) os << '/' << Den; + os << ')'; + } + }; + + + template + struct OutputUnit2< Scale > + { + template + static void fn(Stream &os) + { + os << Den; + if(Num != 1) + os << '/' << Num; + os << '.'; + OutputUnit::fn(os); + } + }; + } + + + template + Str & operator << (Str & os, const Value & value) + { + os << value.get() << ' '; + OutputUnit::fn(os); + return os; + } +} + + +/// +/// Additional Units +/// + +namespace Units +{ + namespace Units + { + typedef Poco::Util::Units::Unit Unit; + + // SI base Units: + + struct m; // meter + struct kg; // kilogram + struct s; // second + struct K; // Kelvin + struct A; // Ampere + struct mol; // mole + struct cd; // candela + } + + UNIT_DISPLAY_NAME(Units::m, "m"); + UNIT_DISPLAY_NAME(Units::kg, "kg"); + UNIT_DISPLAY_NAME(Units::s, "s"); + UNIT_DISPLAY_NAME(Units::K, "K"); + UNIT_DISPLAY_NAME(Units::A, "A"); + UNIT_DISPLAY_NAME(Units::mol, "mol"); + UNIT_DISPLAY_NAME(Units::cd, "cd"); + + namespace Units + { + // SI derived Units: + typedef Compose > rad; + typedef Compose, Power > sr; + typedef Power Hz; + typedef Compose > > N; + typedef Compose > Pa; + typedef Compose J; + typedef Compose > W; + typedef Compose C; + typedef Compose > V; + typedef Compose > F; + typedef Compose > Ohm; + typedef Compose > S; + typedef Compose Wb; + typedef Compose > T; + typedef Compose > H; + typedef cd lm; + typedef Compose > lx; + typedef Power Bq; + typedef Compose > Gy; + typedef Gy Sv; + typedef Compose,mol> kat; + } + + UNIT_DISPLAY_NAME(Units::rad, "rad"); + UNIT_DISPLAY_NAME(Units::sr, "sr"); + // UNIT_DISPLAY_NAME(Units::Hz, "Hz"); // Too problematic + UNIT_DISPLAY_NAME(Units::N, "N"); + UNIT_DISPLAY_NAME(Units::Pa, "Pa"); + UNIT_DISPLAY_NAME(Units::J, "J"); + UNIT_DISPLAY_NAME(Units::W, "W"); + UNIT_DISPLAY_NAME(Units::C, "C"); + UNIT_DISPLAY_NAME(Units::V, "V"); + UNIT_DISPLAY_NAME(Units::F, "F"); + UNIT_DISPLAY_NAME(Units::Ohm, "Ohm"); + UNIT_DISPLAY_NAME(Units::S, "S"); + UNIT_DISPLAY_NAME(Units::Wb, "Wb"); + UNIT_DISPLAY_NAME(Units::T, "T"); + UNIT_DISPLAY_NAME(Units::H, "H"); + UNIT_DISPLAY_NAME(Units::lx, "lx"); + UNIT_DISPLAY_NAME(Units::Gy, "Gy"); + UNIT_DISPLAY_NAME(Units::kat, "kat"); + + namespace Units + { + // SI prefixes: + template struct deca { typedef Scale type; }; + template struct hecto { typedef Scale type; }; + template struct kilo { typedef Scale type; }; + template struct mega { typedef Scale::type, 1, 1000> type; }; + template struct giga { typedef Scale::type, 1, 1000> type; }; + template struct tera { typedef Scale::type, 1, 1000> type; }; + template struct peta { typedef Scale::type, 1, 1000> type; }; + template struct exa { typedef Scale::type, 1, 1000> type; }; + template struct zetta { typedef Scale::type, 1, 1000> type; }; + template struct yotta { typedef Scale::type, 1, 1000> type; }; + + template struct deci { typedef Scale type; }; + template struct centi { typedef Scale type; }; + template struct milli { typedef Scale type; }; + template struct micro { typedef Scale::type, 1000> type; }; + template struct nano { typedef Scale::type, 1000> type; }; + template struct pico { typedef Scale::type, 1000> type; }; + template struct femto { typedef Scale::type, 1000> type; }; + template struct atto { typedef Scale::type, 1000> type; }; + template struct zepto { typedef Scale::type, 1000> type; }; + template struct yocto { typedef Scale::type, 1000> type; }; + + + // Some prefixed SI Units: + typedef centi::type cm; + typedef milli::type mm; + typedef kilo::type km; + typedef milli::type g; + typedef milli::type mg; + typedef milli::type ms; + + + class Prefix + /// Parent class for unit prefixes. + /// Use classes inheriting from this class to scale + /// the values. + { + public: + template + Prefix(const T& val, double multiplier = 1, const std::string& prefix = ""): + _pHolder(new Holder(val)), + _multiplier(multiplier), + _prefix(prefix) + { } + + double value() const + { return _pHolder->get() * _multiplier; } + + void addPrefix(std::ostream& os) const + { os << _prefix; } + + void addUnit(std::ostream& os) const + { _pHolder->appendUnit(os); } + + private: + Prefix(); + + class Placeholder + { + public: + virtual ~Placeholder() { } + virtual double get() const = 0; + virtual void appendUnit(std::ostream& os) const = 0; + }; + + template + struct Holder : public Placeholder + { + typedef Value ValueType; + + Holder (const U& val): _val(ValueType(val)) { } + + double get() const + { return _val.get(); } + + void appendUnit(std::ostream& os) const + { OutputUnit::fn(os); } + + ValueType _val; + }; + + Placeholder* _pHolder; + double _multiplier; + std::string _prefix; + }; + } + + template + Str& streamOp (Str& os, const Units::Prefix& val) + { + os << val.value() << ' '; + val.addPrefix(os); + val.addUnit(os); + return os; + } + + template + Str& operator << (Str& os, const Units::Prefix& val) + /// Streaming operator for prefixed values. + { + return streamOp(os, val); + } + + UNIT_DISPLAY_NAME(Units::cm, "cm"); + UNIT_DISPLAY_NAME(Units::mm, "mm"); + UNIT_DISPLAY_NAME(Units::km, "km"); + UNIT_DISPLAY_NAME(Units::g, "g"); + UNIT_DISPLAY_NAME(Units::mg, "mg"); + UNIT_DISPLAY_NAME(Units::ms, "ms"); + + namespace Units + { + // Non-SI mass + typedef Scale lb; + typedef Scale oz; + typedef Scale tonne; + + // Non-SI temperature + typedef Translate Celsius; + typedef Translate, 32> Fahrenheit; + + // Non-SI time + typedef Scale minute; + typedef Scale hour; + typedef Scale day; + typedef Scale week; + struct month; // No fixed ratio with week + typedef Scale year; + typedef Scale century; + typedef Scale millennium; + + // Non-SI length + typedef Scale inch; + typedef Scale foot; + typedef Scale yard; + typedef Scale mile; + typedef Scale nautical_mile; + + // Non-SI area + typedef Power m2; + typedef Power mm2; + typedef Scale hectare; + typedef Scale are; + typedef Power inch2; + typedef Scale acre; + + // Non-SI volume + typedef Power cm3; + typedef cm3 ml; + typedef Scale liter; + typedef Scale dl; + typedef Scale cl; + typedef Power m3; + + // Non-SI velocity + typedef Compose > mph; + typedef Compose > kph; + typedef Compose > meters_per_second; + typedef Compose > knot; + typedef Scale mach; + + // Angles + typedef Scale degree; + typedef Scale grad; + typedef Scale< degree, 60 > degree_minute; + typedef Scale< degree_minute, 60 > degree_second; + + // Pressure + typedef Scale kPa; + typedef Scale psi; + typedef Scale millibar; + + // Other + typedef Scale rpm; + typedef Scale percent; + typedef Scale dozen; + typedef Scale bakers_dozen; + } + + UNIT_DISPLAY_NAME(Units::lb, "lb"); + UNIT_DISPLAY_NAME(Units::oz, "oz"); + UNIT_DISPLAY_NAME(Units::tonne, "tonnes"); + UNIT_DISPLAY_NAME(Units::Celsius, "'C"); + UNIT_DISPLAY_NAME(Units::Fahrenheit, "'F"); + UNIT_DISPLAY_NAME(Units::minute, "minutes"); + UNIT_DISPLAY_NAME(Units::hour, "hours"); + UNIT_DISPLAY_NAME(Units::day, "days"); + UNIT_DISPLAY_NAME(Units::week, "weeks"); + UNIT_DISPLAY_NAME(Units::month, "months"); + UNIT_DISPLAY_NAME(Units::year, "years"); + UNIT_DISPLAY_NAME(Units::century, "centuries"); + UNIT_DISPLAY_NAME(Units::millennium, "millennia"); + UNIT_DISPLAY_NAME(Units::inch, "inches"); + UNIT_DISPLAY_NAME(Units::foot, "foot"); + UNIT_DISPLAY_NAME(Units::yard, "yards"); + UNIT_DISPLAY_NAME(Units::mile, "miles"); + UNIT_DISPLAY_NAME(Units::nautical_mile, "nautical miles"); + UNIT_DISPLAY_NAME(Units::hectare, "ha"); + UNIT_DISPLAY_NAME(Units::are, "are"); + UNIT_DISPLAY_NAME(Units::acre, "acres"); + UNIT_DISPLAY_NAME(Units::ml, "ml"); + UNIT_DISPLAY_NAME(Units::liter, "l"); + UNIT_DISPLAY_NAME(Units::dl, "dl"); + UNIT_DISPLAY_NAME(Units::cl, "cl"); + UNIT_DISPLAY_NAME(Units::mph, "mph"); + UNIT_DISPLAY_NAME(Units::kph, "km/h"); + UNIT_DISPLAY_NAME(Units::knot, "knots"); + UNIT_DISPLAY_NAME(Units::mach, "mach"); + UNIT_DISPLAY_NAME(Units::degree, "deg"); + UNIT_DISPLAY_NAME(Units::grad, "grad"); + UNIT_DISPLAY_NAME(Units::degree_minute, "'"); + UNIT_DISPLAY_NAME(Units::degree_second, "\""); + UNIT_DISPLAY_NAME(Units::kPa, "kPa"); + UNIT_DISPLAY_NAME(Units::psi, "PSI"); + UNIT_DISPLAY_NAME(Units::millibar, "millibars"); + UNIT_DISPLAY_NAME(Units::percent, "%"); + UNIT_DISPLAY_NAME(Units::rpm, "rpm"); + UNIT_DISPLAY_NAME(Units::dozen, "dozen"); + UNIT_DISPLAY_NAME(Units::bakers_dozen, "bakers dozen"); + + namespace Values + { + typedef Value Unit; + + // SI Units + typedef Value m; + typedef Value kg; + typedef Value s; + typedef Value K; + typedef Value A; + typedef Value mol; + typedef Value cd; + + // SI derived + typedef Value rad; + typedef Value sr; + typedef Value Hz; + typedef Value N; + typedef Value Pa; + typedef Value J; + typedef Value W; + typedef Value C; + typedef Value V; + typedef Value F; + typedef Value Ohm; + typedef Value S; + typedef Value Wb; + typedef Value T; + typedef Value H; + typedef Value lm; + typedef Value lx; + typedef Value Bq; + typedef Value Gy; + typedef Value Sv; + typedef Value kat; + + // Prefixed Units + typedef Value cm; + typedef Value mm; + typedef Value km; + typedef Value g; + typedef Value mg; + typedef Value ms; + + // Non-SI + typedef Value lb; + typedef Value oz; + typedef Value tonne; + + typedef Value Celsius; + typedef Value Fahrenheit; + + typedef Value minute; + typedef Value hour; + typedef Value day; + typedef Value week; + typedef Value month; + typedef Value year; + typedef Value century; + typedef Value millennium; + + typedef Value inch; + typedef Value foot; + typedef Value yard; + typedef Value mile; + typedef Value nautical_mile; + + typedef Value m2; + typedef Value mm2; + typedef Value hectare; + typedef Value are; + typedef Value inch2; + typedef Value acre; + + typedef Value cm3; + typedef Value ml; + typedef Value cl; + typedef Value liter; + typedef Value dl; + typedef Value m3; + + typedef Value mph; + typedef Value kph; + typedef Value meters_per_second; + typedef Value knot; + typedef Value mach; + + typedef Value degree; + typedef Value grad; + typedef Value degree_minute; + typedef Value degree_second; + + typedef Value kPa; + typedef Value psi; + typedef Value millibar; + + typedef Value percent; + typedef Value rpm; + typedef Value dozen; + typedef Value bakers_dozen; + + #define DEFINE_PREFIX_CLASS(name, scale, prefix) struct name: public Units::Prefix \ + { template name(const T& val): Prefix(val, scale, prefix) { } }; \ + template Str& operator << (Str& os, const name& val) \ + { return streamOp(os, val); } + + DEFINE_PREFIX_CLASS (deca, .1, "da") + DEFINE_PREFIX_CLASS (hecto, .01, "h") + DEFINE_PREFIX_CLASS (kilo, .001, "k") + DEFINE_PREFIX_CLASS (mega, 1e-6, "M") + DEFINE_PREFIX_CLASS (giga, 1e-9, "G") + DEFINE_PREFIX_CLASS (tera, 1e-12, "T") + DEFINE_PREFIX_CLASS (peta, 1e-15, "P") + DEFINE_PREFIX_CLASS (exa, 1e-18, "E") + DEFINE_PREFIX_CLASS (zetta, 1e-21, "Z") + DEFINE_PREFIX_CLASS (yotta, 1e-24, "Y") + + DEFINE_PREFIX_CLASS (deci, 10, "d") + DEFINE_PREFIX_CLASS (centi, 100, "c") + DEFINE_PREFIX_CLASS (milli, 1000, "m") + DEFINE_PREFIX_CLASS (micro, 1e6, "u") + DEFINE_PREFIX_CLASS (nano, 1e9, "n") + DEFINE_PREFIX_CLASS (pico, 1e12, "p") + DEFINE_PREFIX_CLASS (femto, 1e15, "f") + DEFINE_PREFIX_CLASS (atto, 1e18, "a") + DEFINE_PREFIX_CLASS (zepto, 1e21, "z") + DEFINE_PREFIX_CLASS (yocto, 1e24, "y") + } + + namespace Constants + { + // Physical constants: + const Value > > k (1.3806504e-23); + const Value mu (1.660538782e-27); + const Value > NA (6.02214179e23); + const Value G0 (7.7480917004e-5); + const Value > > e0 (8.854187817e-12); + const Value me (9.10938215e-31); + const Value eV (1.602176487e-19); + const Value e (1.602176487e-19); + const Value F (96485.3399); + const Value alpha (7.2973525376e-3); + const Value inv_alpha (137.035999679); + const Value > > u0 (12.566370614); + const Value phi0 (2.067833667e-15); // ?? + const Value, Power > > > R (8.314472); + const Value, Compose, Power > > > G (6.67428e-11); + const Value > h (6.62606896e-34); + const Value > h_bar (1.054571628e-34); + const Value mp (1.672621637e-27); + const Value mpme (1836.15267247); + const Value > Rinf (10973731.568527); + const Value > > c (299792458); + const Value, Power > > > rho (5.6704e-8); + + // Other constants: + const Value pi (3.141592653589793); + const Value lightyear (9.4605284e15); + const Value AU(149597871); + const Value > > g (9.80665); + } + + + // Trigonometry + + template + V sin(const Value & angle) + { + return std::sin(Value(angle).get()); + } + + + template + V cos(const Value & angle) + { + return std::cos(Value(angle).get()); + } + + + template + V tan(const Value & angle) + { + return std::tan(Value(angle).get()); + } + + +} } } // namespace Poco::Util::Units + + +#endif // Util_Units_INCLUDED diff --git a/Util/samples/Makefile b/Util/samples/Makefile index c449430a5..109868ede 100644 --- a/Util/samples/Makefile +++ b/Util/samples/Makefile @@ -11,3 +11,4 @@ clean all: projects projects: $(MAKE) -C SampleApp $(MAKECMDGOALS) $(MAKE) -C SampleServer $(MAKECMDGOALS) + $(MAKE) -C Units $(MAKECMDGOALS) diff --git a/Util/samples/Units/Makefile b/Util/samples/Units/Makefile new file mode 100644 index 000000000..796a05a81 --- /dev/null +++ b/Util/samples/Units/Makefile @@ -0,0 +1,17 @@ +# +# Makefile +# +# $Id: //poco/svn/Util/samples/SampleServer/Makefile#1 $ +# +# Makefile for Poco SampleServer +# + +include $(POCO_BASE)/build/rules/global + +objects = Units + +target = Units +target_version = 1 +target_libs = PocoUtil PocoFoundation + +include $(POCO_BASE)/build/rules/exec diff --git a/Util/samples/Units/Units_vs71.vcproj b/Util/samples/Units/Units_vs71.vcproj new file mode 100644 index 000000000..4970d055f --- /dev/null +++ b/Util/samples/Units/Units_vs71.vcproj @@ -0,0 +1,267 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Util/samples/Units/Units_vs80.vcproj b/Util/samples/Units/Units_vs80.vcproj new file mode 100644 index 000000000..3e7a9252c --- /dev/null +++ b/Util/samples/Units/Units_vs80.vcproj @@ -0,0 +1,390 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Util/samples/Units/Units_vs90.vcproj b/Util/samples/Units/Units_vs90.vcproj new file mode 100644 index 000000000..6aaf705bc --- /dev/null +++ b/Util/samples/Units/Units_vs90.vcproj @@ -0,0 +1,379 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Util/samples/Units/src/Units.cpp b/Util/samples/Units/src/Units.cpp new file mode 100644 index 000000000..93a12636b --- /dev/null +++ b/Util/samples/Units/src/Units.cpp @@ -0,0 +1,121 @@ +// +// Units.cpp +// +// $Id: //poco/svn/Util/samples/Units/src/Units.cpp#1 $ +// +// This sample demonstrates the Units. +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + + +#include "Poco/Util/Units.h" +#include + +using namespace Poco::Util::Units::Values; +using namespace Poco::Util::Units::Constants; + +using Poco::Util::Units::square; +using Poco::Util::Units::cube; + +namespace Poco { +namespace Util { +namespace Units { +namespace Units { +typedef Compose, Power > SpecificWeight;// [kN/m^3] +} // namespace Units +namespace Values { +typedef Value SpecificWeight; +} } } } // namespace Poco::Util::Units + + +int main() +{ + std::cout << "One mile is " << km(mile(1)) << std::endl; + // Output: One mile is 1.60934 km + + std::cout << "Flow rate is " << m3(mile(1)*inch(80)*foot(9))/s(minute(5)) << std::endl; + // Output: Flow rate is 29.9026 (m)^3.(s)^-1 + + hour h; + //h = cm(3); // Compile-time error: incompatible units + //h = 4; // Compile-time error: 4 of what? + h = day(4); // Ok: h is 96 hours + + m l = cm(42); + std::cout << cm(42) << " == " << l << " == " << milli(l) << std::endl; + std::cout << "Area of circle with radius " << l << + " is " << mm2(square(l) * pi) << std::endl; + + SpecificWeight sw(9.81); // water + + std::cout << "Volume of a water cube with side size " << m(0.1) << + " is " << liter(cube(m(0.1))) << + " and weighs " << N(sw * cube(m(.1))) << std::endl; + + m radius_equator(6378135); + m radius_pole(6356750); + m3 vol((pi * square(radius_equator) * radius_pole) * 4/3); + + std::cout << "Volume of Earth is " << vol + << " (" << yotta(liter(vol)) << ")" << std::endl; + std::cout << "It takes " << minute(AU/c) << " for a Sun beam to reach Earth." << std::endl; + + + std::cout << std::endl << m(1) << " is:" << std::endl; + std::cout << "-------------" << std::endl; + + std::cout << deca(m(1)) << std::endl; + std::cout << hecto(m(1)) << std::endl; + std::cout << kilo(m(1)) << std::endl; + std::cout << mega(m(1)) << std::endl; + std::cout << giga(m(1)) << std::endl; + std::cout << tera(m(1)) << std::endl; + std::cout << peta(m(1)) << std::endl; + std::cout << exa(m(1)) << std::endl; + std::cout << zetta(m(1)) << std::endl; + std::cout << yotta(m(1)) << std::endl; + + std::cout << deci(m(1)) << std::endl; + std::cout << centi(m(1)) << std::endl; + std::cout << milli(m(1)) << std::endl; + std::cout << micro(m(1)) << std::endl; + std::cout << nano(m(1)) << std::endl; + std::cout << pico(m(1)) << std::endl; + std::cout << femto(m(1)) << std::endl; + std::cout << atto(m(1)) << std::endl; + std::cout << zepto(m(1)) << std::endl; + std::cout << yocto(m(1)) << std::endl; + + return 0; +} +/* +int main() +{ + typedef units::compose< units::units::m, units::pow > meters_per_second; + meters_per_second ms(100); +} +*/ diff --git a/Util/samples/samples_vs80.sln b/Util/samples/samples_vs80.sln index b67282450..9f74a9cae 100644 --- a/Util/samples/samples_vs80.sln +++ b/Util/samples/samples_vs80.sln @@ -4,6 +4,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SampleApp", "SampleApp\Samp EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SampleServer", "SampleServer\SampleServer_vs80.vcproj", "{0CFFC7B0-04F4-4A60-B6E4-84D78EDA2C73}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Units", "Units\Units_vs80.vcproj", "{68D2608B-1915-4985-A671-1BA101959FA6}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution debug_shared|Win32 = debug_shared|Win32 @@ -28,6 +30,14 @@ Global {0CFFC7B0-04F4-4A60-B6E4-84D78EDA2C73}.release_shared|Win32.Build.0 = release_shared|Win32 {0CFFC7B0-04F4-4A60-B6E4-84D78EDA2C73}.release_static|Win32.ActiveCfg = release_static|Win32 {0CFFC7B0-04F4-4A60-B6E4-84D78EDA2C73}.release_static|Win32.Build.0 = release_static|Win32 + {68D2608B-1915-4985-A671-1BA101959FA6}.debug_shared|Win32.ActiveCfg = debug_shared|Win32 + {68D2608B-1915-4985-A671-1BA101959FA6}.debug_shared|Win32.Build.0 = debug_shared|Win32 + {68D2608B-1915-4985-A671-1BA101959FA6}.debug_static|Win32.ActiveCfg = debug_static|Win32 + {68D2608B-1915-4985-A671-1BA101959FA6}.debug_static|Win32.Build.0 = debug_static|Win32 + {68D2608B-1915-4985-A671-1BA101959FA6}.release_shared|Win32.ActiveCfg = release_shared|Win32 + {68D2608B-1915-4985-A671-1BA101959FA6}.release_shared|Win32.Build.0 = release_shared|Win32 + {68D2608B-1915-4985-A671-1BA101959FA6}.release_static|Win32.ActiveCfg = release_static|Win32 + {68D2608B-1915-4985-A671-1BA101959FA6}.release_static|Win32.Build.0 = release_static|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE