Squashed 'third_party/boostorg/units/' content from commit 57389b7

Change-Id: Id8ff79c1508f6103e20808f7a038f6a30d113b08
git-subtree-dir: third_party/boostorg/units
git-subtree-split: 57389b7374a6f7a4caf87cc44092bb8d0db65ec6
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..3e84d7c
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,96 @@
+* text=auto !eol svneol=native#text/plain
+*.gitattributes text svneol=native#text/plain
+
+# Scriptish formats
+*.bat        text svneol=native#text/plain
+*.bsh        text svneol=native#text/x-beanshell
+*.cgi        text svneol=native#text/plain
+*.cmd        text svneol=native#text/plain
+*.js         text svneol=native#text/javascript
+*.php        text svneol=native#text/x-php
+*.pl         text svneol=native#text/x-perl
+*.pm         text svneol=native#text/x-perl
+*.py         text svneol=native#text/x-python
+*.sh         eol=lf svneol=LF#text/x-sh
+configure    eol=lf svneol=LF#text/x-sh
+
+# Image formats
+*.bmp        binary svneol=unset#image/bmp
+*.gif        binary svneol=unset#image/gif
+*.ico        binary svneol=unset#image/ico
+*.jpeg       binary svneol=unset#image/jpeg
+*.jpg        binary svneol=unset#image/jpeg
+*.png        binary svneol=unset#image/png
+*.tif        binary svneol=unset#image/tiff
+*.tiff       binary svneol=unset#image/tiff
+*.svg        text svneol=native#image/svg%2Bxml
+
+# Data formats
+*.pdf        binary svneol=unset#application/pdf
+*.avi        binary svneol=unset#video/avi
+*.doc        binary svneol=unset#application/msword
+*.dsp        text svneol=crlf#text/plain
+*.dsw        text svneol=crlf#text/plain
+*.eps        binary svneol=unset#application/postscript
+*.gz         binary svneol=unset#application/gzip
+*.mov        binary svneol=unset#video/quicktime
+*.mp3        binary svneol=unset#audio/mpeg
+*.ppt        binary svneol=unset#application/vnd.ms-powerpoint
+*.ps         binary svneol=unset#application/postscript
+*.psd        binary svneol=unset#application/photoshop
+*.rdf        binary svneol=unset#text/rdf
+*.rss        text svneol=unset#text/xml
+*.rtf        binary svneol=unset#text/rtf
+*.sln        text svneol=native#text/plain
+*.swf        binary svneol=unset#application/x-shockwave-flash
+*.tgz        binary svneol=unset#application/gzip
+*.vcproj     text svneol=native#text/xml
+*.vcxproj    text svneol=native#text/xml
+*.vsprops    text svneol=native#text/xml
+*.wav        binary svneol=unset#audio/wav
+*.xls        binary svneol=unset#application/vnd.ms-excel
+*.zip        binary svneol=unset#application/zip
+
+# Text formats
+.htaccess    text svneol=native#text/plain
+*.bbk        text svneol=native#text/xml
+*.cmake      text svneol=native#text/plain
+*.css        text svneol=native#text/css
+*.dtd        text svneol=native#text/xml
+*.htm        text svneol=native#text/html
+*.html       text svneol=native#text/html
+*.ini        text svneol=native#text/plain
+*.log        text svneol=native#text/plain
+*.mak        text svneol=native#text/plain
+*.qbk        text svneol=native#text/plain
+*.rst        text svneol=native#text/plain
+*.sql        text svneol=native#text/x-sql
+*.txt        text svneol=native#text/plain
+*.xhtml      text svneol=native#text/xhtml%2Bxml
+*.xml        text svneol=native#text/xml
+*.xsd        text svneol=native#text/xml
+*.xsl        text svneol=native#text/xml
+*.xslt       text svneol=native#text/xml
+*.xul        text svneol=native#text/xul
+*.yml        text svneol=native#text/plain
+boost-no-inspect text svneol=native#text/plain
+CHANGES      text svneol=native#text/plain
+COPYING      text svneol=native#text/plain
+INSTALL      text svneol=native#text/plain
+Jamfile      text svneol=native#text/plain
+Jamroot      text svneol=native#text/plain
+Jamfile.v2   text svneol=native#text/plain
+Jamrules     text svneol=native#text/plain
+Makefile*    text svneol=native#text/plain
+README       text svneol=native#text/plain
+TODO         text svneol=native#text/plain
+
+# Code formats
+*.c          text svneol=native#text/plain
+*.cpp        text svneol=native#text/plain
+*.h          text svneol=native#text/plain
+*.hpp        text svneol=native#text/plain
+*.ipp        text svneol=native#text/plain
+*.tpp        text svneol=native#text/plain
+*.jam        text svneol=native#text/plain
+*.java       text svneol=native#text/plain
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..b103bf5
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,157 @@
+# Use, modification, and distribution are
+# subject to the Boost Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+#
+# Copyright Rene Rivera 2015-2016.
+
+sudo: false
+dist: trusty
+language: cpp
+
+branches:
+  only:
+    - master
+    - develop
+
+env:
+  global:
+    # see: http://www.boost.org/build/doc/html/bbv2/overview/invocation.html#bbv2.overview.invocation.properties
+    # to use the default for a given environment, comment it out; recommend you build debug and release however..
+    # - B2_ADDRESS_MODEL=address-model=64,32
+    # - B2_LINK=link=shared,static
+    # - B2_THREADING=threading=multi,single
+    - B2_VARIANT=variant=release,debug
+
+install:
+  - export SELF=`basename $TRAVIS_BUILD_DIR`
+  - cd ..
+  - git clone -b $TRAVIS_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root
+  - cd boost-root
+  - git submodule update --init tools/boostdep
+  - git submodule update --init tools/build
+  - git submodule update --init tools/inspect
+  - cp -r $TRAVIS_BUILD_DIR/* libs/$SELF
+  - export BOOST_ROOT="`pwd`"
+  - export PATH="`pwd`":$PATH
+  - python tools/boostdep/depinst/depinst.py $SELF
+  - ./bootstrap.sh
+  - ./b2 headers
+
+addons:
+  apt:
+    packages:
+      - binutils-gold
+      - gdb
+      - libc6-dbg
+
+script:
+  - |-
+    echo "using $TOOLSET : : $COMPILER : <cxxflags>-std=$CXXSTD ;" > ~/user-config.jam
+  - ./b2 libs/$SELF/test toolset=$TOOLSET $CXXFLAGS $LINKFLAGS $B2_ADDRESS_MODEL $B2_LINK $B2_THREADING $B2_VARIANT -j3
+
+
+jobs:
+  include:
+    # C++03 using stock compilers
+    - os: linux
+      env:
+        - TOOLSET=gcc
+        - CXXSTD=c++03
+    - os: linux
+      env:
+        - TOOLSET=clang
+        - CXXSTD=c++03
+
+    # C++17 using the latest compilers
+    - os: linux
+      env:
+        - TOOLSET=gcc
+        - COMPILER=g++-7
+        - CXXSTD=c++17
+      addons:
+        apt:
+          packages:
+            - g++-7
+          sources:
+            - ubuntu-toolchain-r-test
+    - os: linux
+      env:
+        - TOOLSET=clang
+        - COMPILER=clang++-5.0
+        - CXXSTD=c++17
+      addons:
+        apt:
+          packages:
+            - clang-5.0
+            - g++-7
+          sources:
+            - llvm-toolchain-trusty-5.0
+            - ubuntu-toolchain-r-test
+
+    - os: osx
+      env:
+        - TOOLSET=clang
+        - CXXSTD=c++03
+
+    - os: osx
+      osx_image: xcode9.1
+      env:
+        - TOOLSET=clang
+        - CXXSTD=c++03
+
+    # Coverity Scan - runs on pull requests into master
+    - os: linux
+      if: branch = master or branch = develop
+      script:
+        - echo -n | openssl s_client -connect scan.coverity.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' | sudo tee -a /etc/ssl/certs/ca-
+        - libs/$SELF/covscan.sh
+      env:
+        - COMMENT="Coverity Scan"
+
+    # UBSAN build
+    - os: linux
+      env:
+        - COMMENT="UBSAN"
+        - B2_VARIANT=variant=debug
+        - TOOLSET=clang
+        - COMPILER=clang++-5.0
+        - CXXSTD=c++03
+        - CXXFLAGS="cxxflags=-fno-omit-frame-pointer cxxflags=-fsanitize=undefined cxxflags=-fsanitize=integer"
+        - LINKFLAGS="linkflags=-fsanitize=undefined"
+      addons:
+        apt:
+          packages:
+            - clang-5.0
+            - g++-7
+          sources:
+            - llvm-toolchain-trusty-5.0
+            - ubuntu-toolchain-r-test
+
+after_success:
+  # If this is not a profiling build skip the rest...
+  - if [[ "$COVERALL" -ne "1" ]]; then exit 0; fi
+
+  # Copying Coveralls data to a separate folder
+  - wget https://github.com/linux-test-project/lcov/archive/v1.13.zip
+  - unzip v1.13.zip
+  - LCOV="`pwd`/lcov-1.13/bin/lcov --gcov-tool gcov-6"
+
+  # Preparing Coveralls data
+  - mkdir -p $TRAVIS_BUILD_DIR/coverals
+  - $LCOV --directory bin.v2/libs/$SELF --base-directory libs/$SELF --capture --output-file $TRAVIS_BUILD_DIR/coverals/coverage.info --no-external
+  - $LCOV --remove $TRAVIS_BUILD_DIR/coverals/coverage.info "*/$SELF/test/*" --output-file $TRAVIS_BUILD_DIR/coverals/coverage-filtered.info
+
+  # Sending data to Coveralls
+  - cd $TRAVIS_BUILD_DIR
+  - gem install coveralls-lcov
+  - coveralls-lcov coverals/coverage-filtered.info
+
+notifications:
+  email:
+    recipients:
+      - jhunold@gmx.eu
+
+
+cache:
+  directories:
+    - $HOME/boost-root
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..685cb46
--- /dev/null
+++ b/README.md
@@ -0,0 +1,38 @@
+Boost.Units
+===========
+
+Boost.Units, part of collection of the [Boost C++ Libraries](http://github.com/boostorg),
+implements dimensional analysis in a general and extensible manner,
+treating it as a generic compile-time metaprogramming problem.
+With appropriate compiler optimization, no runtime execution cost is introduced,
+facilitating the use of this library to provide dimension checking in performance-critical code.
+
+### Directories
+
+* **doc** - QuickBook documentation sources
+* **example** - examples
+* **images** - images for documention
+* **include** - Interface headers
+* **test** - unit tests
+* **test_headers** - unit tests for self containment of headers
+* **tutorial** - tutorial
+
+### Test results
+
+@       | Travis      | AppVeyor
+--------|-------------|---------
+master  | [![Build Status](https://travis-ci.org/boostorg/units.svg?branch=master)](https://travis-ci.org/boostorg/units) | [![Build Status](https://ci.appveyor.com/api/projects/status/github/boostorg/units?branch=master&svg=true)](https://ci.appveyor.com/project/boostorg/units)
+develop | [![Build Status](https://travis-ci.org/boostorg/units.svg)](https://travis-ci.org/boostorg/units) | [![Build Status](https://ci.appveyor.com/api/projects/status/github/boostorg/units?svg=true)](https://ci.appveyor.com/project/boostorg/units)
+
+<a href="https://scan.coverity.com/projects/boostorg-units">
+  <img alt="Coverity Scan Build Status"
+       src="https://img.shields.io/coverity/scan/14037.svg"/>
+</a>
+
+### More information
+
+* [Documentation](http://boost.org/libs/units)
+
+### License
+
+Distributed under the [Boost Software License, Version 1.0](http://www.boost.org/LICENSE_1_0.txt).
diff --git a/appveyor.yml b/appveyor.yml
new file mode 100644
index 0000000..bdd583e
--- /dev/null
+++ b/appveyor.yml
@@ -0,0 +1,92 @@
+# Copyright 2016, 2017 Peter Dimov
+# Copyright (C) 2017 James E. King III
+# Distributed under the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt)
+
+# When copying this to a new library, be sure to update the name of the library
+# in two places (once each at the top of install: and test_script:)
+
+version: 1.0.{build}-{branch}
+
+notifications:
+  - provider: Email
+    to:
+      - jhunold@gmx.eu
+    on_build_status_changed: true
+
+shallow_clone: true
+
+branches:
+  only:
+    - develop
+    - master
+
+matrix:
+  allow_failures:
+    - MAYFAIL: true
+
+environment:
+  global:
+    # see: http://www.boost.org/build/doc/html/bbv2/overview/invocation.html#bbv2.overview.invocation.properties
+    # to use the default for a given environment, comment it out; recommend you build debug and release however..
+    # on Windows it is important to exercise all the possibilities, especially shared vs static
+    B2_ADDRESS_MODEL: address-model=64,32
+    # B2_LINK: link=shared,static
+    # B2_THREADING: threading=multi,single
+    B2_VARIANT: variant=release,debug
+
+  matrix:
+    - COMMENT: Visual Studio Releases
+      APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013
+      TOOLSET: msvc-9.0,msvc-10.0,msvc-11.0,msvc-12.0
+    - COMMENT: Visual Studio 2015
+      APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
+      TOOLSET: msvc-14.0
+      CXXFLAGS: cxxstd=14,17
+    - COMMENT: Visual Studio 2017
+      APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
+      TOOLSET: msvc-14.1
+      CXXFLAGS: cxxstd=14,17
+    - COMMENT: mingw-w64 32-bit
+      APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013
+      ADDPATH: C:\mingw-w64\i686-6.3.0-posix-dwarf-rt_v5-rev1\mingw64\bin;
+      B2_ADDRESS_MODEL: address-model=32
+      TOOLSET: gcc
+      CXXFLAGS: cxxstd=03,11
+  #   MAYFAIL: true
+    - COMMENT: mingw-w64 64-bit
+      APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013
+      ADDPATH: C:\mingw-w64\x86_64-6.3.0-posix-seh-rt_v5-rev1\mingw64\bin;
+      B2_ADDRESS_MODEL: address-model=64
+      TOOLSET: gcc
+      CXXFLAGS: cxxstd=03,11
+
+### other builds for reference..
+  # - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013
+  #   TOOLSET: msvc-11.0
+  #   COMMENT: Visual Studio 2012
+  # - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013
+  #   TOOLSET: msvc-12.0
+  #   COMMENT: Visual Studio 2013
+  # - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
+  #   TOOLSET: msvc-14.0
+
+install:
+  - set SELF=units
+  - cd ..
+  - git clone -b %APPVEYOR_REPO_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root
+  - cd boost-root
+  - git submodule update -q --init tools/boostdep
+  - git submodule update -q --init tools/build
+  - git submodule update -q --init tools/inspect
+  - xcopy /s /e /q %APPVEYOR_BUILD_FOLDER% libs\%SELF%
+  - python tools/boostdep/depinst/depinst.py --include example %SELF%
+  - cmd /c bootstrap
+  - b2 headers
+
+build: off
+
+test_script:
+  - set SELF=units
+  - PATH=%ADDPATH%%PATH%
+  - b2 libs/%SELF%/test toolset=%TOOLSET% %CXXFLAGS% %CXXSTD% %DEFINES% %B2_ADDRESS_MODEL% %B2_LINK% %B2_THREADING% %B2_VARIANT% -j3
diff --git a/boost.css b/boost.css
new file mode 100644
index 0000000..9f8d4bd
--- /dev/null
+++ b/boost.css
@@ -0,0 +1,65 @@
+/*=============================================================================
+    Copyright 2002 William E. Kempf
+    Distributed under the Boost Software License, Version 1.0. (See accompany-
+    ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+
+H1
+{
+    FONT-SIZE: 200%;
+    COLOR: #00008B;
+}
+H2
+{
+    FONT-SIZE: 150%;
+}
+H3
+{
+    FONT-SIZE: 125%;
+}
+H4
+{
+    FONT-SIZE: 108%;
+}
+BODY
+{
+    FONT-SIZE: 100%;
+    BACKGROUND-COLOR: #ffffff;
+}
+PRE
+{
+    MARGIN-LEFT: 2em;
+    FONT-FAMILY: Courier,
+                 monospace;
+}
+CODE
+{
+    FONT-FAMILY: Courier,
+                 monospace;
+}
+CODE.as_pre
+{
+    white-space: pre;
+}
+.index
+{
+    TEXT-ALIGN: left;
+}
+.page-index
+{
+    TEXT-ALIGN: left;
+}
+.definition
+{
+    TEXT-ALIGN: left;
+}
+.footnote
+{
+    FONT-SIZE: 66%;
+    VERTICAL-ALIGN: super;
+    TEXT-DECORATION: none;
+}
+.function-semantics
+{
+    CLEAR: left;
+}
\ No newline at end of file
diff --git a/covscan.sh b/covscan.sh
new file mode 100755
index 0000000..88e08d3
--- /dev/null
+++ b/covscan.sh
@@ -0,0 +1,38 @@
+#! /bin/bash
+#
+# Copyright 2017 James E. King, III
+# Distributed under the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+#      http://www.boost.org/LICENSE_1_0.txt)
+#
+# Bash script to run in travis to perform a Coverity Scan build
+#
+
+#
+# Environment Variables
+#
+# COVERITY_SCAN_NOTIFICATION_EMAIL  - email address to notify
+# COVERITY_SCAN_TOKEN               - the Coverity Scan token (should be secure)
+# SELF                              - the boost libs directory name
+
+set -ex
+
+pushd /tmp
+rm -rf coverity_tool.tgz cov-analysis*
+wget -nv https://scan.coverity.com/download/linux64 --post-data "token=$COVERITY_SCAN_TOKEN&project=boostorg/$SELF" -O coverity_tool.tgz
+tar xzf coverity_tool.tgz
+COVBIN=$(echo $(pwd)/cov-analysis*/bin)
+export PATH=$COVBIN:$PATH
+popd
+
+cd libs/$SELF/test
+../../../b2 toolset=gcc clean
+rm -rf cov-int/
+cov-build --dir cov-int ../../../b2 toolset=gcc -q -j3
+tar cJf cov-int.tar.xz cov-int/
+curl --form token="$COVERITY_SCAN_TOKEN" \
+     --form email="$COVERITY_SCAN_NOTIFICATION_EMAIL" \
+     --form file=@cov-int.tar.xz \
+     --form version="$(git describe --tags)" \
+     --form description="boostorg/$SELF" \
+     https://scan.coverity.com/builds?project="boostorg/$SELF"
diff --git a/doc/Jamfile.v2 b/doc/Jamfile.v2
new file mode 100644
index 0000000..d06495b
--- /dev/null
+++ b/doc/Jamfile.v2
@@ -0,0 +1,224 @@
+# Units documentation Jamfile
+#
+# Copyright (c) 2007-2008
+# Steven Watanabe
+#
+# Distributed under the Boost Software License, Version 1.0. (See
+# accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt
+
+import path ;
+import quickbook ;
+using boostbook ;
+using doxygen ;
+import print ;
+import regex ;
+import sequence ;
+
+path-constant here : . ;
+
+rule run_doxygen ( target : files * : name )
+{
+    doxygen $(target)
+      :
+        $(files)
+      :
+        <doxygen:param>EXTRACT_ALL=YES
+        <doxygen:param>EXPAND_ONLY_PREDEF=YES
+
+        # Horribly ugly, but then macros usually are :(
+        <doxygen:param>"PREDEFINED= \\
+            \"BOOST_MPL_ASSERT(expr)=\" \\
+            \"BOOST_UNITS_STATIC_CONSTANT(a,b)=static const b a\" \\
+            \"BOOST_UNITS_AUTO_STATIC_CONSTANT(a,b)=static const auto a = b\" \\
+            \"BOOST_UNITS_TYPEOF(a)=typeof(a)\" \\
+            \"BOOST_PREVENT_MACRO_SUBSTITUTION=\" \\
+            \"BOOST_UNITS_HAS_TYPEOF=1\" \\
+            \"BOOST_UNITS_DEFINE_BASE_UNIT_WITH_CONVERSIONS(namespace_, name_, name_string, symbol_, factor, other_unit, id)= \\
+                namespace boost { namespace units { namespace namespace_ { \\
+                    struct name_ ## _base_unit : boost::units::base_unit<name_ ## _base_unit, other_unit::dimension_type, id> { \\
+                        static const char* name(); \\
+                        static const char* symbol(); \\
+                    }; \\
+                } } }\" \\
+            \"BOOST_UNITS_DOXYGEN=1\""
+        <doxygen:param>HIDE_UNDOC_MEMBERS=NO
+        <doxygen:param>EXTRACT_PRIVATE=NO
+        <doxygen:param>ENABLE_PREPROCESSING=YES
+        <doxygen:param>MACRO_EXPANSION=YES
+        $(expand)
+        <doxygen:param>SEARCH_INCLUDES=NO
+        <reftitle>$(name)
+    ;
+
+}
+
+run_doxygen units_reference
+  :
+    [ glob $(here)/../../../boost/units/*.hpp :
+           $(here)/../../../boost/units/physical_dimensions.hpp ]
+  :
+    "Units Reference"
+  ;
+
+run_doxygen si_reference
+  :
+    $(here)/../../../boost/units/systems/si.hpp
+    [ path.glob-tree $(here)/../../../boost/units/systems/si : *.hpp : detail ]
+  :
+    "SI System Reference"
+  ;
+
+run_doxygen cgs_reference
+  :
+    $(here)/../../../boost/units/systems/cgs.hpp
+    [ path.glob-tree $(here)/../../../boost/units/systems/cgs : *.hpp : detail ]
+  :
+    "CGS System Reference"
+  ;
+
+rule make_base_units_doc ( directory : name )
+{
+    run_doxygen $(directory)_base_units_reference
+      :
+        [ path.glob-tree $(here)/../../../boost/units/base_units/$(directory) : *.hpp : detail conversions.hpp ]
+      :
+        "$(name) Base Units Reference"
+      ;
+}
+
+make_base_units_doc angle : Angle ;
+make_base_units_doc astronomical : Astronomical ;
+make_base_units_doc cgs : CGS ;
+make_base_units_doc imperial : Imperial ;
+make_base_units_doc information : Information ;
+make_base_units_doc metric : Metric ;
+make_base_units_doc si : SI ;
+make_base_units_doc temperature : Temperature ;
+make_base_units_doc us : US ;
+
+all_base_units_doc = angle astronomical cgs imperial information metric si temperature us ;
+all_base_units_doc = $(all_base_units_doc)_base_units_reference ;
+
+run_doxygen dimensions_reference
+  :
+    $(here)/../../../boost/units/physical_dimensions.hpp
+    [ path.glob-tree $(here)/../../../boost/units/physical_dimensions : *.hpp : detail ]
+  :
+    "Dimensions Reference"
+  ;
+
+run_doxygen trig_reference
+  :
+    #../../../boost/units/systems/trig.hpp
+    [ path.glob-tree $(here)/../../../boost/units/systems/angle : *.hpp : detail ]
+  :
+    "Trigonometry and Angle System Reference"
+  ;
+
+run_doxygen temperature_reference
+  :
+    [ path.glob-tree $(here)/../../../boost/units/systems/temperature : *.hpp : detail ]
+  :
+    "Temperature System Reference"
+  ;
+
+run_doxygen information_reference
+  :
+    $(here)/../../../boost/units/systems/information.hpp
+    [ path.glob-tree $(here)/../../../boost/units/systems/information : *.hpp : detail prefixes.hpp ]
+  :
+    "Information System Reference"
+  ;
+
+run_doxygen abstract_reference
+  :
+    $(here)/../../../boost/units/systems/abstract.hpp
+  :
+    "Abstract System Reference"
+  ;
+
+rule less ( a b )
+{
+    if [ path.basename $(a) ]  < [ path.basename $(b) ] 
+    {
+        return true ;
+    }
+}
+
+rule generate-qbk ( target : sources * : properties * )
+{
+    print.output $(target) ;
+    local as-path = [ sequence.transform path.make : $(sources:G=) ] ;
+    local known = ;
+    local duplicated = ;
+    for local file in $(as-path)
+    {
+        local base = [ path.basename $(file) ] ;
+        if $(base) in $(known)
+        {
+            if ! $(base) in $(duplicated)
+            {
+                duplicated += $(base) ;
+            }
+        } else
+        {
+            known += $(base) ;
+        }
+    }
+    for local file in [ sequence.insertion-sort $(as-path) : less ]
+    {
+        local output_filename = [ path.relative-to [ path.make $(here)/../../.. ] $(file) ] ;
+        local base_filename = [ path.basename $(file) ] ;
+        local base_unit = [ regex.replace $(base_filename) "\\.hpp" "" ] ;
+        if $(base_filename) in $(duplicated)
+        {
+            # tack the directory name onto the end
+            local dir-name = [ path.basename [ path.parent $(file) ] ] ;
+            base_unit = "$(base_unit) ($(dir-name))" ;
+        }
+        print.text "[headerref $(output_filename) $(base_unit)][br]" : overwrite ;
+    }
+}
+
+make base_units.qbk : [ path.glob-tree $(here)/../../../boost/units/base_units : *.hpp : detail conversions.hpp ] : @generate-qbk ;
+explicit base_units ;
+
+install base_units_install : base_units.qbk : <location>. ;
+
+xml units
+  :
+    units.qbk
+  :
+    <dependency>base_units_install
+    <dependency>units_reference
+    <dependency>si_reference
+    <dependency>cgs_reference
+    <dependency>$(all_base_units_doc)
+    <dependency>dimensions_reference
+    <dependency>trig_reference
+    <dependency>temperature_reference
+    <dependency>information_reference
+    <dependency>abstract_reference
+;
+
+boostbook standalone
+  :
+    units
+  :
+    <xsl:param>toc.max.depth=1
+    <xsl:param>toc.section.depth=8
+    <xsl:param>chunk.section.depth=8
+    <xsl:param>boost.root="../../../.."
+    <format>pdf:<xsl:param>boost.url.prefix=http://www.boost.org/doc/libs/release/doc/html
+;
+
+###############################################################################
+alias boostdoc
+    : units
+    :
+    :
+    : ;
+explicit boostdoc ;
+alias boostrelease ;
+explicit boostrelease ;
diff --git a/doc/units.qbk b/doc/units.qbk
new file mode 100644
index 0000000..0c7345f
--- /dev/null
+++ b/doc/units.qbk
@@ -0,0 +1,1475 @@
+[library Boost.Units
+  [quickbook 1.5]
+  [version 1.1.0]
+  [authors [Schabel, Matthias C.]]
+  [authors [Watanabe, Steven]]
+  [copyright 2003-2008 Matthias Christian Schabel, 2007-2010 Steven Watanabe]
+  [license
+      Distributed under the Boost Software License, Version 1.0.
+      (See accompanying file LICENSE_1_0.txt or copy at
+      [@http://www.boost.org/LICENSE_1_0.txt])
+  ]
+  [purpose zero-overhead compile-time dimensional analysis and unit computations]
+]
+
+[/ Some links to external sources.]
+[def __boost [@http://www.boost.org/ Boost]]
+[def __boostroot [@boost: Boost root]]
+[def __boostlicense [@http://www.boost.org/LICENSE_1_0.txt Boost License]]
+[def __boost_mpl [@http://www.boost.org/libs/mpl/doc/index.html Boost Metaprogramming Library]]
+
+[def __mpl_forward_sequence [@http://www.boost.org/libs/mpl/doc/refmanual/forward-sequence.html MPL Forward Sequence]]
+
+[/Links within this document.]
+[def __ordinal [classref boost::units::ordinal ordinal]]
+[def __dim [classref boost::units::dim dim]]
+[def __static_rational [classref boost::units::static_rational static_rational]]
+[def __make_dimension_list [classref boost::units::make_dimension_list make_dimension_list]]
+[def __unit [classref boost::units::unit unit]]
+[def __base_unit_info [classref boost::units::base_unit_info base_unit_info]]
+[def __quantity [classref boost::units::quantity quantity]]
+[def __conversion_helper [classref boost::units::conversion_helper conversion_helper]]
+[def __absolute [classref boost::units::absolute absolute]]
+[def __base_unit [classref boost::units::base_unit base_unit]]
+[def __base_dimension [classref boost::units::base_dimension base_dimension]]
+[def __scaled_base_unit [classref boost::units::scaled_base_unit base_unit]]
+[def __make_scaled_unit [classref boost::units::make_scaled_unit make_scaled_unit]]
+
+[def __unary_plus_typeof_helper [classref boost::units::unary_plus_typeof_helper unary_plus_typeof_helper]]
+[def __unary_minus_typeof_helper [classref boost::units::unary_minus_typeof_helper unary_minus_typeof_helper]]
+[def __add_typeof_helper [classref boost::units::add_typeof_helper add_typeof_helper]]
+[def __subtract_typeof_helper [classref boost::units::subtract_typeof_helper subtract_typeof_helper]]
+[def __multiply_typeof_helper [classref boost::units::multiply_typeof_helper multiply_typeof_helper]]
+[def __divide_typeof_helper [classref boost::units::divide_typeof_helper divide_typeof_helper]]
+[def __power_typeof_helper [classref boost::units::power_typeof_helper power_typeof_helper]]
+[def __root_typeof_helper [classref boost::units::root_typeof_helper root_typeof_helper]]
+
+[def __static_negate [classref boost::units::static_negate static_negate]]
+[def __static_add [classref boost::units::static_add static_add]]
+[def __static_subtract [classref boost::units::static_subtract static_subtract]]
+[def __static_multiply [classref boost::units::static_multiply static_multiply]]
+[def __static_divide [classref boost::units::static_divide static_divide]]
+[def __static_power [classref boost::units::static_power static_power]]
+[def __static_root [classref boost::units::static_root static_root]]
+
+[def __get_dimension [classref boost::units::get_dimension get_dimension]]
+[def __get_system [classref boost::units::get_system get_system]]
+
+[def __pow [funcref boost::units::pow pow]]
+[def __root [funcref boost::units::root root]]
+[def __quantity_cast [funcref boost::units::quantity_cast quantity_cast]]
+
+[def __from_value [memberref boost::units::quantity::from_value from_value]]
+[def __value [memberref boost::units::quantity::value value]]
+
+[def __reduce_unit [classref boost::units::reduce_unit reduce_unit]]
+[def __unscale [classref boost::units::unscale unscale]]
+
+[def __BOOST_UNITS_STATIC_CONSTANT [macroref BOOST_UNITS_STATIC_CONSTANT]]
+[def __BOOST_UNITS_DEFINE_CONVERSION_FACTOR [macroref BOOST_UNITS_DEFINE_CONVERSION_FACTOR]]
+[def __BOOST_UNITS_DEFINE_CONVERSION_FACTOR_TEMPLATE [macroref BOOST_UNITS_DEFINE_CONVERSION_FACTOR_TEMPLATE]]
+[def __BOOST_UNITS_DEFAULT_CONVERSION [macroref BOOST_UNITS_DEFAULT_CONVERSION]]
+
+[section:Introduction Introduction]
+
+The Boost.Units library is a C++ implementation of dimensional analysis in a general 
+and extensible manner, treating it as a generic compile-time metaprogramming problem. With appropriate
+compiler optimization, no runtime execution cost is introduced, facilitating the use of this library to
+provide dimension checking in performance-critical code. Support for units
+and quantities (defined as a unit and associated value) for arbitrary unit system models and arbitrary  
+value types is provided, as is a fine-grained general facility for unit conversions. Complete SI and CGS unit 
+systems are provided, along with systems for 
+angles measured in degrees, radians, gradians, and revolutions and 
+systems for temperatures measured in Kelvin, degrees Celsius and degrees Fahrenheit. 
+The library architecture has been designed with flexibility and extensibility in mind; demonstrations of the ease
+of adding new units and unit conversions are provided in the examples.
+
+In order to enable complex compile-time dimensional analysis calculations with no runtime overhead,
+Boost.Units relies heavily on the [___boost_mpl] (MPL) and on template metaprogramming techniques, and is, as a consequence, 
+fairly demanding of compiler compliance to ISO standards. At present, it has been successfully
+compiled and tested on the following compilers/platforms :
+
+# g++ 4.0.1 on Mac OSX 10.4
+# Intel CC 9.1, 10.0, and 10.1 on Mac OSX 10.4
+# g++ 3.4.4, 4.2.3, and 4.3.0 on Windows XP
+# Microsoft Visual C++ 7.1, 8.0, and 9.0 on Windows XP
+# Comeau 4.3.10.1 beta2 on Windows XP
+# Metrowerks CodeWarrior 9.2 on Windows XP.  
+# Sun CC 5.9 on Solaris and Linux
+
+The following compilers/platforms are known *not* to work :
+
+# g++ 3.3.x
+# Microsoft Visual C++ 6.0 on Windows XP
+# Microsoft Visual C++ 7.0 on Windows XP
+# Metrowerks CodeWarrior 8.0 on Windows XP.
+# All versions of Borland.
+
+[endsect]
+
+[section:Quick_Start Quick Start]
+
+Before discussing the basics of the library, we first define a few terms that will be used frequently
+in the following :
+
+*  *Base dimension* : A base dimension is loosely defined as a measurable entity of interest; in conventional 
+   dimensional analysis, base dimensions include length (\[L\]), mass (\[M\]), time (\[T\]), etc... but there is
+   no specific restriction on what base dimensions can be used. Base dimensions are essentially a tag type and 
+   provide no dimensional analysis functionality themselves.
+*  *Dimension* : A collection of zero or more base dimensions, each
+   potentially raised to a different rational power.
+   For example, length = \[L\]^1, area = \[L\]^2, velocity = \[L\]^1/\[T\]^1, and
+   energy = \[M\]^1 \[L\]^2/\[T\]^2 are all dimensions.
+*  *Base unit* : A base unit represents a specific measure of a dimension. For example, while length is an abstract measure of
+   distance, the meter is a concrete base unit of distance.  Conversions are defined using base units.
+   Much like base dimensions, base units are a tag type used solely to define units and do not support dimensional
+   analysis algebra.
+*  *Unit* : A set of base units raised to rational exponents, e.g. m^1, kg^1, m^1/s^2.
+*  *System* : A unit system is a collection of base units representing all the measurable entities of interest for a 
+   specific problem. For example, the SI unit system defines seven base units : length (\[L\]) in meters, 
+   mass (\[M\]) in kilograms, time (\[T\]) in seconds, current (\[I\]) in amperes, temperature (\[theta\]) in kelvin, 
+   amount (\[N\]) in moles, and luminous intensity (\[J\]) in candelas. All measurable entities within the SI system can 
+   be represented as products of various integer or rational powers of these seven base units.
+*  *Quantity* : A quantity represents a concrete amount of a unit. Thus, while the meter is the base 
+   unit of length in the SI system, 5.5 meters is a quantity of length in that system.
+
+To begin, we present two short tutorials. [@../../libs/units/tutorial/tutorial_1.cpp Tutorial1] demonstrates the use of 
+[@http://en.wikipedia.org/wiki/SI_units SI] units. After including the appropriate system headers 
+and the headers for the various SI units we will need (all SI units can be included with  
+[headerref boost/units/systems/si.hpp]) and for quantity I/O ([headerref boost/units/io.hpp]), we define 
+a function that computes the work, in joules, done by exerting a force in newtons over a specified distance in meters 
+and outputs the result to `std::cout`. The [___quantity] class accepts a second template parameter as its value type; 
+this parameter defaults to
+`double` if not otherwise specified. To demonstrate the ease of using user-defined types in dimensional
+calculations, we also present code for computing the complex impedance using `std::complex<double>`
+as the value type :
+
+[import ../example/tutorial.cpp]
+
+[tutorial_code]
+
+The intent and function of the above code should be obvious; the output produced is :
+
+[tutorial_output]
+
+While this library attempts to make simple dimensional computations easy to code, it is in no way
+tied to any particular unit system (SI or otherwise). Instead, it provides a highly flexible compile-time
+system for dimensional analysis, supporting arbitrary collections of base dimensions, rational 
+powers of units, and explicit quantity conversions. It accomplishes all of this via template metaprogramming techniques.
+With modern optimizing compilers, this results in zero runtime overhead for quantity computations relative to the
+same code without unit checking.
+
+[endsect]
+
+[section:Dimensional_Analysis Dimensional Analysis]
+
+The concept of 
+[@http://en.wikipedia.org/wiki/Dimensional_analysis dimensional analysis] 
+is normally presented early on in introductory physics and engineering classes as a means of determining the  
+correctness of an equation or computation by propagating the physical measurement
+[@http://en.wikipedia.org/wiki/Units_of_measurement units]
+of various quantities through the equation along with their numerical values. There are a number of standard 
+unit systems in common use, the most prominent of which is the 
+[@http://en.wikipedia.org/wiki/SI_units Systeme International] 
+(also known as SI or MKS (meter-kilogram-second), which was a metric predecessor to the SI system named 
+for three of the base units on which the system is based). The SI  
+is the only official international standard unit system and is widely utilized in science and engineering. 
+Other common systems include the [@http://en.wikipedia.org/wiki/Cgs_units CGS]
+(centimeter-gram-second) system and the 
+[@http://en.wikipedia.org/wiki/English_units English]
+system still in use in some problem domains in the United States and elsewhere. In physics, 
+there also exist a number of other systems that are in common use in specialized subdisciplines. These are 
+collectively referred to as [@http://en.wikipedia.org/wiki/Natural_units natural units]. When 
+quantities representing different measurables are combined, dimensional analysis provides the means of 
+assessing the consistency of the resulting calculation. For example, the sum of two lengths is also a length, 
+while the product of two lengths is an area, and the sum of a length and an area is undefined. The fact that the
+arguments to many functions (such as exp, log, etc...) must be dimensionless quantities can be easily demonstrated by 
+examining their series expansions in the context of dimensional analysis. This library facilitates the enforcement 
+of this type of restriction in code involving dimensioned quantities where appropriate.
+
+In the following discussion we view dimensional analysis as an abstraction in which an arbitrary set of 
+[@http://en.wikipedia.org/wiki/Fundamental_units units] obey the rules of a specific algebra. 
+We will refer to a pair of a base dimension and a rational exponent as a *fundamental dimension*, 
+and a list composed of an arbitrary number of fundamental dimensions as a *composite dimension* or, simply,
+*dimension*. In particular, given a set of [$../../libs/units/images/form_0.png] fundamental dimensions
+denoted by [$../../libs/units/images/form_1.png] and a set of [$../../libs/units/images/form_0.png]
+rational exponents [$../../libs/units/images/form_2.png], any possible (composite) dimension can be written
+as [$../../libs/units/images/form_3.png].  
+
+Composite dimensions obey the algebraic rules for dimensional analysis. In particular, for any scalar value,
+[$../../libs/units/images/form_4.png], 
+and composite dimensions [$../../libs/units/images/form_5.png]
+and [$../../libs/units/images/form_6.png], where 
+[$../../libs/units/images/form_7.png], we have:
+
+[$../../libs/units/images/form_8.png]
+
+Users of a dimensional analysis library should be able to specify an arbitrary list of base dimensions to 
+produce a composite dimension. This potentially includes repeated tags. For example, 
+it should be possible to express energy as [$../../libs/units/images/form_9.png], [$../../libs/units/images/form_10.png], 
+[$../../libs/units/images/form_11.png], or any other permutation of mass, length, and time having aggregate exponents of 
+1, 2, and -2, respectively.
+In order to be able to perform computations on arbitrary sets of dimensions, 
+all composite dimensions must be reducible to an unambiguous final composite dimension, which we will refer to as a 
+*reduced dimension*, for which
+
+# fundamental dimensions are consistently ordered
+# dimensions with zero exponent are elided. Note that reduced dimensions never have more than 
+  [$../../libs/units/images/form_0.png] base dimensions, one for each distinct fundamental dimension, but may have fewer.
+
+In our implementation, base dimensions are associated with tag types. As we will ultimately 
+represent composite dimensions as typelists, we must provide some mechanism for  sorting
+base dimension tags in order to make it possible to convert an arbitrary composite dimension
+into a reduced dimension.  For this purpose, we assign a unique integer to each base dimension.
+The [___base_dimension] class (found in [headerref boost/units/base_dimension.hpp]) uses the
+curiously recurring template pattern (CRTP) technique to ensure that ordinals specified for
+base dimensions are unique:
+
+    template<class Derived, long N> struct base_dimension { ... };
+
+With this, we can define the base dimensions for length, mass, and time as:
+
+[import ../example/test_system.hpp]
+[test_system_snippet_1]
+
+It is important to note that the choice of order is completely arbitrary as long as each tag has a unique enumerable
+value; non-unique ordinals are flagged as errors at compile-time. Negative ordinals are reserved for use by the library.  
+To define composite dimensions corresponding to the base dimensions, we
+simply create MPL-conformant typelists of fundamental dimensions by using the [___dim] class to encapsulate pairs of base dimensions 
+and [___static_rational] exponents.  The [___make_dimension_list] class acts as a wrapper to ensure
+that the resulting type is in the form of a reduced dimension:
+
+[test_system_snippet_2]
+
+This can also be easily accomplished using a convenience typedef provided by [___base_dimension]:
+
+[test_system_snippet_3]
+
+so that the above code is identical to the full typelist definition. Composite dimensions are similarly defined via a typelist:
+
+[test_system_snippet_4]
+
+A convenience class for composite dimensions with integer powers is also provided:
+
+[test_system_snippet_5]
+
+[endsect]
+
+[section:Units Units]
+
+We define a *unit* as a set of base units each of which can be raised to an arbitrary rational
+exponent.  Thus, the SI unit corresponding to the dimension of force is kg m s^-2, where kg, m,
+and s are base units.  We use the notion of a *unit system* such as SI to specify the mapping
+from a dimension to a particular unit so that instead of specifying the base units explicitly,
+we can just ask for the representation of a dimension in a particular system.
+
+Units are, like dimensions, purely compile-time variables with no associated value.
+Units obey the same algebra as dimensions do; the presence of the unit system serves to ensure that units having identical
+reduced dimension in different systems (like feet and meters) cannot be inadvertently mixed in computations.
+
+There are two distinct types of systems that can be envisioned:
+
+* *Homogeneous systems* : Systems which hold a linearly independent set of base units which
+  can be used to represent many different dimensions. For example, the SI system has seven
+  base dimensions and seven base units corresponding to them.  It can represent any unit which
+  uses only those seven base dimensions.  Thus it is a homogeneous_system.
+* *Heterogeneous systems* : Systems which store the exponents of every base unit involved
+  are termed heterogeneous.  Some units can only be represented in this way.  For example,
+  area in m ft is intrinsically heterogeneous, because the base units of meters and feet
+  have identical dimensions.  As a result, simply storing a dimension and a set of base
+  units does not yield a unique solution.   A practical example of the need for heterogeneous
+  units, is an empirical equation used in  aviation: H = (r/C)^2 where H is the radar beam
+  height in feet and r is the radar range in nautical miles. In order to  enforce dimensional
+  correctness of this equation, the constant, C, must be expressed in nautical miles per foot^(1/2),
+  mixing two distinct base units of length.
+
+Units are implemented by the [___unit] template class defined in [headerref boost/units/unit.hpp] :
+
+    template<class Dim,class System> class unit;
+
+In addition to supporting the compile-time dimensional analysis operations, the +, -, *, and / runtime operators are provided
+for [___unit] variables. Because the dimension associated with powers and roots must be computed at compile-time, it is not 
+possible to provide overloads for `std::pow` that function correctly for [___unit]s. These operations are supported through 
+free functions [___pow] and [___root] that are templated on integer and [___static_rational] values and can take as an argument 
+any type for which the utility classes [___power_typeof_helper] and [___root_typeof_helper] have been defined.
+
+[section Base Units]
+
+Base units are defined much like base dimensions.
+
+    template<class Derived, class Dimensions, long N> struct base_unit { ... };
+
+Again negative ordinals are reserved.
+
+As an example, in the following we will implement a subset of the SI unit system based on the fundamental dimensions 
+given above, demonstrating all steps necessary for a completely functional system. First, we simply define a unit system
+that includes type definitions for commonly used units:
+
+[test_system_snippet_6]
+
+The macro [___BOOST_UNITS_STATIC_CONSTANT] is provided in [headerref boost/units/static_constant.hpp] 
+to facilitate ODR- and thread-safe constant definition in header files. We then define some constants for the supported units 
+to simplify variable definitions:
+
+[test_system_snippet_7]
+
+If support for textual output of units is desired, we can also specialize the [___base_unit_info] class for each fundamental 
+dimension tag:
+
+[test_system_snippet_8]
+
+and similarly for `kilogram_base_unit` and `second_base_unit`. A future version of the library will provide a more flexible system
+allowing for internationalization through a facet/locale-type mechanism. 
+The `name()` and `symbol()` methods of [___base_unit_info] provide full and short names for the base unit. With these definitions, 
+we have the rudimentary beginnings of our unit system, which can be used to determine reduced dimensions for arbitrary 
+unit calculations.
+
+[endsect] [/section Base Units]
+
+[section Scaled Base Units]
+
+Now, it is also possible to define a base unit as being a multiple of
+another base unit.  For example, the way that `kilogram_base_unit` is
+actually defined by the library is along the following lines
+
+    struct gram_base_unit : boost::units::base_unit<gram_base_unit, mass_dimension, 1> {};
+    typedef scaled_base_unit<gram_base_unit, scale<10, static_rational<3> > > kilogram_base_unit;
+
+This basically defines a kilogram as being 10^3 times a gram.
+
+There are several advantages to this approach.
+
+* It reflects the real meaning of these units better than treating them as independent units.
+* If a conversion is defined between grams or kilograms and some other units,
+  it will automatically work for both kilograms and grams, with only one specialization.
+* Similarly, if the symbol for grams is defined as "g", then the symbol for kilograms
+  will be "kg" without any extra effort.
+
+[endsect] [/section Scaled Base Units]
+
+[section Scaled Units]
+
+We can also scale a [___unit] as a whole, rather than scaling the individual
+base units which comprise it.  For this purpose, we use the metafunction
+[___make_scaled_unit].  The main motivation for this feature is the metric
+prefixes defined in [headerref boost/units/systems/si/prefixes.hpp].
+
+A simple example of its usage would be.
+
+    typedef make_scaled_unit<si::time, scale<10, static_rational<-9> > >::type nanosecond;
+
+nanosecond is a specialization of [___unit], and can be used in a quantity normally.
+
+    quantity<nanosecond> t(1.0 * si::seconds);
+    std::cout << t << std::endl;    // prints 1e9 ns
+
+[endsect] [/section Scaled Units]
+
+[endsect] [/section:Units Units]
+
+[section:Quantities Quantities]
+
+A *quantity* is defined as a value of an arbitrary value type that is associated with a specific unit. For example,
+while meter is a unit, 3.0 meters is a quantity. Quantities obey two separate algebras: the native algebra for their 
+value type, and the dimensional analysis algebra for the associated unit. In addition, algebraic operations are defined
+between units and quantities to simplify the definition of quantities; it is effectively equivalent to algebra with
+a unit-valued quantity.
+
+Quantities are implemented by the [___quantity] template class defined in [headerref boost/units/quantity.hpp] :
+
+    template<class Unit,class Y = double> class quantity;
+
+This class is templated on both unit type (`Unit`) and value type (`Y`), with the latter defaulting to double-precision
+floating point if not otherwise specified.  The value type must have a normal copy constructor and copy
+assignment operator.  Operators +, -, *, and / are provided for algebraic operations between 
+scalars and units, scalars and quantities, units and quantities, and between quantities. In addition, integral and
+rational powers and roots can be computed using the [___pow]<R> and [___root]<R> functions. Finally,  
+the standard set of boolean comparison operators ( `==, !=,  <, <=, >, and >=` ) are provided to allow 
+comparison of quantities from the same unit system.  All operators simply delegate to the
+corresponding operator of the value type if the units permit.
+
+[section:Heterogeneous_Operators Heterogeneous Operators]
+
+For most common value types, the result type of arithmetic operators is the same as the value type itself. For example, 
+the sum of two double precision floating point numbers is another double precision floating point number. However, there 
+are instances where this is not the case. A simple example is given by the [@http://en.wikipedia.org/wiki/Natural_number 
+natural numbers] where the operator arithmetic obeys the following rules (using the standard notation for 
+[@http://en.wikipedia.org/wiki/Number number systems]):
+
+* [$../../libs/units/images/form_12.png]
+* [$../../libs/units/images/form_13.png]
+* [$../../libs/units/images/form_14.png]
+* [$../../libs/units/images/form_15.png]
+
+This library is designed to support arbitrary value type algebra for addition, subtraction, multiplication, division, and 
+rational powers and roots.  It uses Boost.Typeof to deduce the result of these operators.  For compilers that
+support `typeof`, the appropriate value type will be automatically deduced.  For compilers that do not provide
+language support for `typeof` it is necessary to register all the types used.  For the case of natural numbers,
+this would amount to something like the following:
+
+    BOOST_TYPEOF_REGISTER_TYPE(natural);
+    BOOST_TYPEOF_REGISTER_TYPE(integer);
+    BOOST_TYPEOF_REGISTER_TYPE(rational);
+
+[endsect]
+
+[section:Conversions Conversions]
+
+Conversion is only meaningful for quantities as it implies the presence of at 
+least a multiplicative scale factor and, possibly, and affine linear offset.
+Macros for simplifying the definition of conversions between units can be found in
+[headerref boost/units/conversion.hpp] and [headerref boost/units/absolute.hpp]
+(for affine conversions with offsets). 
+
+The macro [___BOOST_UNITS_DEFINE_CONVERSION_FACTOR] specifies a scale
+factor for conversion from the first unit type to the second.  The
+first argument must be a [___base_unit].  The second argument
+can be either a [___base_unit] or a [___unit].
+
+Let's declare a simple base unit:
+
+    struct foot_base_unit : base_unit<foot_base_unit, length_dimension, 10> { };
+
+Now, we want to be able to convert feet to meters and vice versa.  The foot
+is defined as exactly 0.3048 meters, so we can write the following
+
+    BOOST_UNITS_DEFINE_CONVERSION_FACTOR(foot_base_unit, meter_base_unit, double, 0.3048);
+
+Alternately, we could use the SI length `typedef`:
+
+    BOOST_UNITS_DEFINE_CONVERSION_FACTOR(foot_base_unit, SI::length, double, 0.3048);
+
+Since the SI unit of length is the meter, these two definitions are equivalent.
+If these conversions have been defined, then converting between
+scaled forms of these units will also automatically work.
+
+The macro [___BOOST_UNITS_DEFAULT_CONVERSION] specifies a conversion
+that will be applied to a base unit when no direct conversion is
+possible.  This can be used to make arbitrary conversions work
+with a single specialization:
+
+    struct my_unit_tag : boost::units::base_unit<my_unit_tag, boost::units::force_type, 1> {};
+    // define the conversion factor
+    BOOST_UNITS_DEFINE_CONVERSION_FACTOR(my_unit_tag, SI::force, double, 3.14159265358979323846);
+    // make conversion to SI the default.
+    BOOST_UNITS_DEFAULT_CONVERSION(my_unit_tag, SI::force);
+
+[endsect]
+
+[section:Quantity_Construction_and_Conversion Construction and Conversion of Quantities]
+
+This library is designed to emphasize safety above convenience when performing operations with dimensioned quantities.
+Specifically, construction of quantities is required to fully specify both value and unit. Direct construction from a scalar value
+is prohibited (though the static member function [___from_value] is provided to enable 
+this functionality where it is necessary. In addition, a [___quantity_cast] to a reference allows direct access to the 
+underlying value of a [___quantity] variable. An explicit constructor is provided to enable conversion between
+dimensionally compatible quantities in different unit systems.  Implicit conversions between unit systems are
+allowed only when the reduced units are identical, allowing, for example, trivial conversions between
+equivalent units in different systems (such as SI seconds and CGS seconds) while simultaneously enabling
+unintentional unit system mismatches to be caught at compile time and preventing potential loss of precision and
+performance overhead from unintended conversions.  Assignment follows the same rules.
+An exception is made for quantities for which the unit reduces to dimensionless; in this case, implicit conversion
+to the underlying value type is allowed via class template specialization. Quantities of different value types are implicitly 
+convertible only if the value types are themselves implicitly convertible. The [___quantity] class also defines
+a `value()` member for directly accessing the underlying value.
+
+To summarize, conversions are allowed under the following conditions :
+
+* implicit conversion of `quantity<Unit,Y>` to `quantity<Unit,Z>` is allowed if `Y` and `Z` are implicitly convertible.
+* assignment between `quantity<Unit,Y>` and `quantity<Unit,Z>` is allowed if `Y` and `Z` are implicitly convertible.
+* explicit conversion between `quantity<Unit1,Y>` and `quantity<Unit2,Z>` is allowed if `Unit1` and `Unit2` have the same dimensions
+    and if `Y` and `Z` are implicitly convertible.
+* implicit conversion between `quantity<Unit1,Y>` and `quantity<Unit2,Z>` is allowed if `Unit1` 
+    reduces to exactly the same combination of base units as `Unit2` and if `Y` and `Z` are convertible.
+* assignment between `quantity<Unit1,Y>` and `quantity<Unit2,Z>` is allowed under the same
+  conditions as implicit conversion.
+* `quantity<Unit,Y>` can be directly constructed from a value of type `Y` using the static member function [___from_value]. Doing so, 
+  naturally, bypasses any type-checking of the newly assigned value, so this method should be used only when absolutely necessary.
+
+Of course, any time implicit conversion is allowed, an explicit conversion is
+also legal.
+
+Because dimensionless quantities have no associated units, they behave as normal scalars, and allow implicit conversion to and from 
+the underlying value type or types that are convertible to/from that value type.
+
+[endsect]
+
+[endsect]
+
+[section:Examples Examples]
+
+[section:DimensionExample Dimension Example]
+
+([@../../libs/units/example/dimension.cpp dimension.cpp])
+
+By using MPL metafunctions and the template specializations for operations on composite dimensions
+(defined in [headerref boost/units/dimension.hpp]) it is possible to perform compile time arithmetic
+according to the dimensional analysis rules described [link boost_units.Dimensional_Analysis above]
+to produce new composite dimensions :
+
+[import ../example/dimension.cpp]
+
+[dimension_snippet_1]
+
+outputting (with symbol demangling, implemented in
+[@boost:/boost/units/detail/utility.hpp utility.hpp])
+
+[dimension_output]
+
+[endsect]
+
+[section:UnitExample Unit Example]
+
+([@../../libs/units/example/unit.cpp unit.cpp])
+
+This example demonstrates the use of the simple but functional unit system implemented in 
+[@boost:/libs/units/example/test_system.hpp test_system.hpp]
+
+[import ../example/unit.cpp]
+
+[unit_snippet_1]
+
+We can perform various algebraic operations on these units, resulting in the following output:
+
+[unit_output]
+
+[endsect]
+
+[section:QuantityExample Quantity Example]
+
+([@../../libs/units/example/quantity.cpp quantity.cpp])
+
+This example demonstrates how to use quantities of our toy unit system :
+
+[import ../example/quantity.cpp]
+
+[quantity_snippet_1]
+
+giving us the basic quantity functionality :
+
+[quantity_output_double]
+
+As a further demonstration of the flexibility of the system, we replace the `double` value type 
+with a `std::complex<double>` value type (ignoring the question of the meaningfulness of
+complex lengths and energies) :
+
+[quantity_snippet_2]
+
+and find that the code functions exactly as expected with no additional work, delegating operations 
+to `std::complex<double>` and performing the appropriate dimensional analysis :
+
+[quantity_output_complex]
+
+[endsect]
+
+[section:KitchenSinkExample Kitchen Sink Example using SI units]
+
+([@../../libs/units/example/kitchen_sink.cpp kitchen_sink.cpp])
+
+This example provides a fairly extensive set of tests covering most of the [___quantity] functionality.
+It uses the SI unit system defined in [headerref boost/units/systems/si.hpp].
+
+If we define a few units and associated quantities,
+
+[import ../example/kitchen_sink.cpp]
+
+[kitchen_sink_snippet_1]
+
+the various algebraic operations between scalars, units, and quantities give 
+
+[kitchen_sink_output_1]
+
+Scalar/unit operations :
+
+[kitchen_sink_output_2]
+
+Unit/unit operations and integral/rational powers of units :
+
+[kitchen_sink_output_3]
+
+Scalar/quantity operations :
+
+[kitchen_sink_output_4]
+
+Unit/quantity operations :
+
+[kitchen_sink_output_5]
+
+Quantity/quantity operations and integral/rational powers of quantities :
+
+[kitchen_sink_output_6]
+
+Logical comparison operators are also defined between quantities :
+
+[kitchen_sink_snippet_2]
+
+giving
+
+[kitchen_sink_output_7]
+
+Implicit conversion is allowed between dimensionless quantities and their corresponding value types :
+
+[kitchen_sink_snippet_3]
+
+A generic function for computing mechanical work can be defined that takes force and distance arguments
+in an arbitrary unit system and returns energy in the same system:
+
+[kitchen_sink_function_snippet_3]
+
+[kitchen_sink_snippet_4]
+
+which functions as expected for SI quantities :
+
+[kitchen_sink_output_9]
+
+The ideal gas law can also be implemented in SI units :
+
+[kitchen_sink_function_snippet_4]
+
+[kitchen_sink_snippet_5]
+
+with the resulting output :
+
+[kitchen_sink_output_10]
+
+Trigonometric and inverse trigonometric functions can be implemented for any unit system
+that provides an angular base dimension. For radians, these functions are found in 
+[headerref boost/units/cmath.hpp] These behave as one expects, with trigonometric functions
+taking an angular quantity and returning a dimensionless quantity, while the inverse trigonometric functions
+take a dimensionless quantity and return an angular quantity :
+
+Defining a few angular quantities,
+
+[kitchen_sink_snippet_6]
+
+yields
+
+[kitchen_sink_output_11]
+
+Dealing with complex quantities is trivial. Here is the calculation of complex impedance :
+
+[kitchen_sink_snippet_7]
+
+giving
+
+[kitchen_sink_output_12]
+
+[section:UDT_Quantities User-defined value types]
+
+User-defined value types that support the appropriate arithmetic operations are automatically supported
+as quantity value types. The operators that are supported by default for quantity value types are unary plus, unary minus,
+addition, subtraction, multiplication, division, equal-to, not-equal-to, less-than, less-or-equal-to, 
+greater-than, and greater-or-equal-to. Support for rational powers and roots can be added by overloading
+the [___power_typeof_helper] and [___root_typeof_helper] classes. Here we implement a user-defined `measurement`
+class that models a numerical measurement with an associated measurement error and the appropriate algebra and
+demonstrates its use as a quantity value type; the full code is found in [@../../libs/units/example/measurement.hpp measurement.hpp].
+
+Then, defining some `measurement` [___quantity] variables
+
+[kitchen_sink_snippet_8]
+
+gives
+
+[kitchen_sink_output_13]
+
+If we implement the overloaded helper classes for rational powers and roots
+then we can also compute rational powers of measurement quantities :
+
+[kitchen_sink_output_14]
+
+[endsect]
+
+[endsect]
+
+[section:ConversionExample Conversion Example]
+
+([@../../libs/units/example/conversion.cpp conversion.cpp])
+
+This example demonstrates the various allowed conversions between SI and CGS units. Defining some
+quantities
+
+[import ../example/conversion.cpp]
+
+[conversion_snippet_1]
+
+illustrates implicit conversion of quantities of different value types where implicit conversion 
+of the value types themselves is allowed.  N.B. The conversion from double to int is treated
+as an explicit conversion because there is no way to emulate the exact behavior of the built-in
+conversion.  Explicit constructors allow conversions for two cases:
+
+* explicit casting of a [___quantity] to a different `value_type` :
+
+[conversion_snippet_3]
+
+* and explicit casting of a [___quantity] to a different unit :
+
+[conversion_snippet_4]
+
+giving the following output :
+
+[conversion_output_1]
+
+A few more explicit unit system conversions :
+
+[conversion_snippet_5]
+
+which produces the following output:
+
+[conversion_output_2]
+
+[endsect]
+
+[section:UDTExample User Defined Types]
+
+([@../../libs/units/example/quaternion.cpp quaternion.cpp])
+
+This example demonstrates the use of `boost::math::quaternion` as a value type for  [___quantity] and the converse.
+For the first case, we first define specializations of [___power_typeof_helper] and [___root_typeof_helper] for 
+powers and roots, respectively:
+
+[import ../example/quaternion.cpp]
+
+[quaternion_class_snippet_1a]
+
+[quaternion_class_snippet_1b]
+
+We can now declare a [___quantity] of a `quaternion` :
+
+[quaternion_snippet_1]
+
+so that all operations that are defined in the `quaternion` class behave correctly. If rational
+powers were defined for this class, it would be possible to compute rational powers and roots with
+no additional changes. 
+
+[quaternion_output_1]
+
+Now, if for some reason we preferred the [___quantity] to be the value type of the `quaternion` class we would have :
+
+[quaternion_snippet_2]
+
+Here, the unary plus and minus and addition and subtraction operators function correctly. Unfortunately, 
+the multiplication and division operations fail because `quaternion` implements them in terms of the `*=` and 
+`/=` operators, respectively, which are incapable of representing the heterogeneous unit algebra needed for 
+quantities (an identical problem 
+occurs with `std::complex<T>`, for the same reason). In order to compute rational powers and roots, we need to 
+specialize [___power_typeof_helper] and [___root_typeof_helper] as follows:
+
+[quaternion_class_snippet_2a]
+
+[quaternion_class_snippet_2b]
+
+giving:
+
+[quaternion_output_2]
+
+[endsect]
+
+[section:ComplexExample Complex Example]
+
+([@../../libs/units/example/complex.cpp complex.cpp])
+
+This example demonstrates how to implement a replacement `complex` class that functions correctly both as a 
+quantity value type and as a quantity container class, including heterogeneous multiplication and division 
+operations and rational powers and roots. Naturally, heterogeneous operations are only supported on
+compilers that implement `typeof`. The primary differences are that binary operations are not implemented
+using the `op=` operators and use the utility classes [___add_typeof_helper], [___subtract_typeof_helper], 
+[___multiply_typeof_helper], and [___divide_typeof_helper]. In addition, [___power_typeof_helper] and
+[___root_typeof_helper] are defined for both cases :
+
+[import ../example/complex.cpp]
+
+[complex_class_snippet_1]
+
+With this replacement `complex` class, we can declare a complex variable :
+
+[complex_snippet_1]   
+
+to get the correct behavior for all cases supported by [___quantity] with a `complex` value type :
+
+[complex_output_1]
+
+and, similarly, `complex` with a [___quantity] value type 
+
+[complex_snippet_2]
+
+gives
+
+[complex_output_2]
+
+[endsect]
+
+[section:PerformanceExample Performance Example]
+
+([@../../libs/units/example/performance.cpp performance.cpp])
+
+This example provides an ad hoc performance test to verify that zero runtime overhead 
+is incurred when using [___quantity] in place of `double`. Note that performance 
+optimization and testing is not trivial, so some care must be taken in profiling. It 
+is also critical to have a compiler capable of optimizing the many template instantiations
+and inline calls effectively to achieve maximal performance. Zero overhead for this test
+has been verified using gcc 4.0.1, and icc 9.0, 10.0, and 10.1 on Mac OS 10.4 and 10.5, and
+using msvc 8.0 on Windows XP.
+
+[endsect]
+
+[section:RadarBeamHeightExample Radar Beam Height]
+
+([@../../libs/units/example/radar_beam_height.cpp radar_beam_height.cpp])
+
+[import ../example/radar_beam_height.cpp]
+
+This example demonstrates the implementation of two non-SI units of length, the 
+nautical mile :
+
+[radar_beam_height_class_snippet_1]
+
+and the imperial foot :
+
+[radar_beam_height_class_snippet_2]
+
+These units include conversions between themselves and the meter. Three functions
+for computing radar beam height from radar range and the local earth radius are 
+defined. The first takes arguments in one system and returns a value in the same 
+system :
+
+[radar_beam_height_function_snippet_1]
+
+The second is similar, but is templated on return type, so that the arguments are
+converted to the return unit system internally :
+
+[radar_beam_height_function_snippet_2]
+
+Finally, the third function is an empirical approximation that is only valid for
+radar ranges specified in nautical miles, returning beam height in feet. This 
+function uses the heterogeneous unit of nautical miles per square root of feet to
+ensure dimensional correctness :
+
+[radar_beam_height_function_snippet_3]
+
+With these, we can compute radar beam height in various unit systems :
+
+[radar_beam_height_snippet_1]
+
+giving
+
+[radar_beam_height_output]
+
+[endsect]
+
+[section:HeterogeneousUnitExample Heterogeneous Unit Example]
+
+([@../../libs/units/example/heterogeneous_unit.cpp heterogeneous_unit.cpp])
+
+[import ../example/heterogeneous_unit.cpp]
+
+Mixed units and mixed unit conversions.
+
+This code:
+
+[heterogeneous_unit_snippet_1]
+
+gives
+
+[heterogeneous_unit_output_1]
+
+Arbitrary conversions also work:
+
+[heterogeneous_unit_snippet_2]
+
+yielding
+
+[heterogeneous_unit_output_2]
+
+[endsect]
+
+[section:AbsoluteRelativeTemperatureExample Absolute and Relative Temperature Example]
+
+([@../../libs/units/example/temperature.cpp temperature.cpp])
+
+[import ../example/temperature.cpp]
+
+This example demonstrates using of absolute temperatures and relative temperature differences in Fahrenheit 
+and converting between these and the Kelvin temperature scale. This issue touches on some surprisingly deep mathematical
+concepts (see [@http://en.wikipedia.org/wiki/Affine_space Wikipedia] for a basic review), but for our purposes here, we
+will simply observe that it is important to be able to differentiate between an absolute temperature measurement and a 
+measurement of temperature difference. This is accomplished by using the [___absolute] wrapper class.
+
+First we define a system using the predefined fahrenheit base unit:
+
+[temperature_snippet_1]
+
+Now we can create some quantities:
+
+[temperature_snippet_3]
+
+Note the use of [___absolute] to wrap a unit. The resulting output is:
+
+[temperature_output_1]
+
+[endsect]
+
+[section:RuntimeConversionFactorExample Runtime Conversion Factor Example]
+
+([@../../libs/units/example/runtime_conversion_factor.cpp runtime_conversion_factor.cpp])
+
+[import ../example/runtime_conversion_factor.cpp]
+
+The Boost.Units library does not require that the conversion factors be compile time constants,
+as is demonstrated in this example:
+
+[runtime_conversion_factor_snippet_1]
+
+[endsect]
+
+[section:UnitsWithNonbaseDimensions Units with Non-base Dimensions]
+
+([@../../libs/units/example/non_base_dimension.cpp non_base_dimension.cpp])
+
+[import ../example/non_base_dimension.cpp]
+
+It is also possible to define base units that have derived rather than base dimensions:
+
+[non_base_dimension_snippet_1]
+
+[endsect]
+
+[section:OutputForCompositeUnits Output for Composite Units]
+
+([@../../libs/units/example/composite_output.cpp composite_output.cpp])
+
+[import ../example/composite_output.cpp]
+
+If a unit has a special name and/or symbol, the free functions `name_string` and
+`symbol_string` can be overloaded directly. 
+
+[composite_output_snippet_1]
+
+In this case, any unit that reduces 
+to the overloaded unit will be output with the replacement symbol. 
+
+Special names and symbols for the SI and CGS unit systems are found in 
+[headerref boost/units/systems/si/io.hpp] and [headerref boost/units/systems/cgs/io.hpp], 
+respectively. If these headers are not included, the output will simply follow
+default rules using the appropriate fundamental dimensions. 
+Note that neither of these functions is defined for quantities 
+because doing so would require making assumptions on how the corresponding value
+type should be formatted.
+
+Three `ostream` formatters, `symbol_format`, `name_format`, and `typename_format`
+are provided for convenience. These select the textual representation of units 
+provided by `symbol_string` or `name_string` in the first two cases, while the
+latter returns a demangled typename for debugging purposes. Formatting of scaled
+unit is also done correctly.
+
+[endsect]
+
+[section:autoscale Automatically Scaled Units]
+
+It is often desirable to scale a [___unit] automatically, depending on its value,
+to keep the integral part in a limited range, usually between 1 and 999.
+
+For example, using [@http://en.wikipedia.org/wiki/Engineering_notation engineering notation prefixes],
+
+ "1234.5 m" is more helpfully displayed as "1.234 km"
+ "0.000000001234 m" is more clearly displayed as "1.2345 nanometer".
+
+The iostream manipulators `engineering_prefixes` or `binary_prefixes` make this easy.
+
+[import ../example/autoprefixes.cpp]
+
+[autoprefixes_snippet_1]
+
+(The complete set of [@http://physics.nist.gov/cuu/Units/prefixes.html engineering and scientific multiples]
+is not used (not centi or deci for example), but only powers of ten that are multiples of three, 10^3).
+
+Similarly, the equivalent [@http://en.wikipedia.org/wiki/Binary_prefixes binary prefixes]
+used for displaying computing kilobytes, megabytes, gigabytes...
+
+These are the 2^10 = 1024, 2^20 = 1 048 576, 2^30 ... multiples.
+
+(See also [@http://physics.nist.gov/cuu/Units/binary.html Prefixes for binary multiples]
+
+This scale is specified in IEC 60027-2, Second edition, 2000-11,
+Letter symbols to be used in electrical technology -
+Part 2: Telecommunications and electronics).
+
+[autoprefixes_snippet_2]
+
+But note that scalar dimensionless values, like int, float and double,
+are *not* prefixed automatically by the engineering_prefix or binary_prefix iostream manipulators.
+
+[autoprefixes_snippet_3]
+
+You can output the name or symbol of a unit (rather than the most common quantity of a unit).
+
+[autoprefixes_snippet_4]
+
+Note too that all the formatting flags are persistent,
+so that if you set engineering_prefix, then it applies to all future outputs,
+until you select binary_prefix, or explicitly switch autoprefix off.
+You can specify no prefix (the default of course) in two ways:
+
+[autoprefixes_snippet_5]
+
+And you can get the format flags for diagnosing problems.
+
+[autoprefixes_snippet_6]
+
+[endsect] [/section:autoscale Automatically Scaled Units]
+
+[section:ConversionFactor Conversion Factor]
+
+This code demonstrates the use of the `conversion_factor` free function to determine
+the scale factor between two units.
+
+([@../../libs/units/example/conversion_factor.cpp conversion_factor.cpp])
+
+[import ../example/conversion_factor.cpp]
+
+[conversion_factor_snippet_1]
+
+Produces
+
+[conversion_factor_output]
+
+[endsect]
+
+[section:RuntimeUnits Runtime Units]
+
+([@../../libs/units/example/runtime_unit.cpp runtime_unit.cpp])
+
+[import ../example/runtime_unit.cpp]
+
+This example shows how to implement an interface that
+allow different units at runtime while still maintaining
+type safety for internal calculations.
+
+[runtime_unit_snippet_1]
+
+[endsect]
+
+[section:lambda Interoperability with Boost.Lambda]
+
+([@../../libs/units/example/lambda.cpp lambda.cpp])
+
+[import ../example/lambda.cpp]
+
+The header [headerref boost/units/lambda.hpp] provides overloads
+and specializations needed to make Boost.Units usable with the
+Boost.Lambda library.
+
+[lambda_snippet_1]
+
+[endsect]
+
+[endsect]
+
+[section:Utilities Utilities]
+
+Relatively complete SI and CGS unit systems are provided in [headerref boost/units/systems/si.hpp] and
+[headerref boost/units/systems/cgs.hpp], respectively. 
+
+[section:Metaprogramming_Classes Metaprogramming Classes]
+
+    template<long N> struct ordinal<N>;
+
+    template<typename T,typename V> struct get_tag< dim<T,V> >;
+    template<typename T,typename V> struct get_value< dim<T,V> >;
+    template<class S,class DT> struct get_system_tag_of_dim<S,DT>;
+    template<typename Seq> struct make_dimension_list<Seq>;
+    template<class DT> struct fundamental_dimension<DT>;
+    template<class DT1,int E1,...> struct composite_dimension<DT1,E1,...>;
+
+    template<class Dim,class System> struct get_dimension< unit<Dim,System> >;
+    template<class Unit,class Y> struct get_dimension< quantity<Unit,Y> >;
+    template<class Dim,class System> struct get_system< unit<Dim,System> >;
+    template<class Unit,class Y> struct get_system quantity<Unit,Y> >;
+
+    struct dimensionless_type;
+    template<class System> struct dimensionless_unit<System>;
+    template<class System,class Y> struct dimensionless_quantity<System,Y>;
+
+    struct implicitly_convertible;
+    struct trivial_conversion;
+    template<class T,class S1,class S2> struct base_unit_converter<T,S1,S2>;
+
+    template<class Q1,class Q2> class conversion_helper<Q1,Q2>;
+
+[endsect]
+
+[section:Metaprogramming_Predicates Metaprogramming Predicates]
+
+    template<typename T,typename V> struct is_dim< dim<T,V> >;
+    template<typename T,typename V> struct is_empty_dim< dim<T,V> >;
+
+    template<typename Seq> struct is_dimension_list<Seq>;
+
+    template<class S> struct is_system< homogeneous_system<S> >;
+    template<class S> struct is_system< heterogeneous_system<S> >;
+    template<class S> struct is_homogeneous_system< homogeneous_system<S> >;
+    template<class S> struct is_heterogeneous_system< heterogeneous_system<S> >;
+
+    template<class Dim,class System> struct is_unit< unit<Dim,System> >;
+    template<class Dim,class System> struct is_unit_of_system< unit<Dim,System>,System >;
+    template<class Dim,class System> struct is_unit_of_dimension< unit<Dim,System>,Dim >;
+
+    template<class Unit,class Y> struct is_quantity< quantity<Unit,Y> >;
+    template<class Dim,class System,class Y> struct is_quantity_of_system< quantity<unit<Dim,System>,Y>,System >;
+    template<class Dim,class System,class Y> struct is_quantity_of_dimension< quantity<unit<Dim,System>,Y>,Dim >;
+
+    template<class System> struct is_dimensionless< unit<dimensionless_type,System> >;
+    template<class System> struct is_dimensionless_unit< unit<dimensionless_type,System> >;
+    template<class System,class Y> struct is_dimensionless< quantity<unit<dimensionless_type,System>,Y> >;
+    template<class System,class Y> struct is_dimensionless_quantity< quantity<unit<dimensionless_type,System>,Y> >; 
+
+[endsect]
+
+[endsect]
+
+[section:Reference Reference]
+
+[xinclude units_reference.xml]
+
+[xinclude dimensions_reference.xml]
+[xinclude si_reference.xml]
+[xinclude cgs_reference.xml]
+[xinclude trig_reference.xml]
+[xinclude temperature_reference.xml]
+[xinclude information_reference.xml]
+[xinclude abstract_reference.xml]
+
+[section Base Units by Category]
+
+[xinclude angle_base_units_reference.xml]
+[xinclude astronomical_base_units_reference.xml]
+[xinclude cgs_base_units_reference.xml]
+[xinclude imperial_base_units_reference.xml]
+[xinclude metric_base_units_reference.xml]
+[xinclude si_base_units_reference.xml]
+[xinclude temperature_base_units_reference.xml]
+[xinclude us_base_units_reference.xml]
+
+[endsect]
+
+[section Alphabetical Listing of Base Units]
+[include base_units.qbk]
+[endsect]
+
+[endsect]
+
+[section:Installation Installation]
+
+The core header files are located in `boost/units`. Unit system headers are 
+located in `<boost/units/systems>`. There are no source files for the library
+itself - the library is header-only. Example programs demonstrating various aspects of the library can be found in 
+`boost/libs/units/example`. Programs for unit testing are provided in `boost/libs/units/test`.
+
+[endsect]
+
+[section:FAQ FAQ]
+
+[section:Distinguishing_Quantities_With_Same_Units
+How does one distinguish between quantities that are physically different but have the same units (such as 
+energy and torque)?]
+
+Because Boost.Units includes plane and solid angle units in the SI system, torque and energy 
+are, in fact, distinguishable (see [@http://en.wikipedia.org/wiki/SI_units torque]). 
+In addition, energy is a true
+[@http://mathworld.wolfram.com/Scalar.html scalar] quantity, while torque, despite
+having the same units as energy if plane angle is not included, is in fact a 
+[@http://mathworld.wolfram.com/Pseudovector.html pseudovector]. Thus, a value type representing pseudovectors 
+and encapsulating their algebra could also be implemented. 
+
+There are,
+however, a few SI units that are dimensionally indistinguishable within the SI system. These
+include the [@http://en.wikipedia.org/wiki/Becquerel becquerel], which has units identical to
+frequency (Hz), and the [@http://en.wikipedia.org/wiki/Sievert sievert], which is degenerate
+with the [@http://en.wikipedia.org/wiki/Gray_%28unit%29 gray]. In cases such as this, 
+the proper way to treat this difference is to recognize that expanding the set of base dimensions
+can provide disambiguation.  For example, adding a base dimension for radioactive decays would 
+allow the becquerel to be written as decays/second, differentiating it from the signature of hertz,
+which is simply 1/second.
+
+[endsect]
+
+[section:Angle_Are_Units Angles are treated as units]
+
+If you don't like this, you can just ignore the angle units and 
+go on your merry way (periodically screwing up when a routine wants degrees and you give it 
+radians instead...)
+
+[endsect]
+
+[section:Why_Homogeneous_Systems Why are there homogeneous systems?  Aren't heterogeneous systems sufficient?]
+
+Consider the following code:
+
+    cout << asin(sin(90.0 * degrees));
+
+What should this print?  If only heterogeneous
+systems are available it would print 1.5708 rad
+Why?  Well, `sin` would return a `quantity<dimensionless>`
+effectively losing the information that degrees
+are being used.  In order to propogate this extra information
+we need homogeneous systems.
+
+[endsect]
+
+[section:NoConstructorFromValueType Why can't I construct a quantity directly from the value type?]
+
+This only breaks generic code--which ought to break anyway.  The only
+literal value that ought to be converted to a quantity by generic code
+is zero, which should be handled by the default constructor. In addition,
+consider the search and replace problem allowing this poses:
+
+	quantity<si::length>    q(1.0);
+	
+Here, the intent is clear - we want a length of one in the SI system, which is one meter. However,
+imagine some well-intentioned coder attempting to reuse this code, but to have it perform the
+calculations in the CGS unit system instead. After searching for `si::` and replacing it with `cgs::` ,
+we have:
+
+	quantity<cgs::length>	q(1.0);
+	
+Unfortunately, the meaning of this statement has suddenly changed from one meter to one centimeter. In
+contrast, as implemented, we begin with:
+
+	quantity<si::length>	q(1.0*si::meter);
+	
+and, after search and replace:
+
+	quantity<cgs::length>	q(1.0*cgs::meter);
+	
+which gives us an error. Even if the code has a @using namespace boost::units::si; declaration, the latter
+is still safe, with:
+
+	using namespace boost::units::si;
+	quantity<length>	q(1.0*meter);
+	
+going to
+
+	using namespace boost::units::cgs;
+	quantity<length>	q(1.0*meter);
+	
+The latter will involve an explicit conversion from meters to centimeters, but the value remains correct.
+
+[endsect]
+
+[section:ExplicitConversions Why are conversions explicit by default?]
+
+Safety and the potential for unintended conversions leading to precision loss and hidden performance costs.
+Options are provided for forcing implicit conversions between specific units to be allowed.
+
+[endsect]
+
+[endsect]
+
+[section:Acknowledgements Acknowledgements]
+
+Matthias C. Schabel would like to acknowledge the Department of Defense for its support of this work under 
+the Prostate Cancer Research Program New Investigator Award W81XWH-04-1-0042 and the National Institutes of Health for their
+support of this work under the NIBIB Mentored Quantitative Research Development Award K25EB005077.
+
+Thanks to David Walthall for his assistance in debugging and testing on a variety of platforms and Torsten Maehne for
+his work on interfacing the Boost Units and Boost Lambda libraries.
+
+Thanks to:
+
+* Paul Bristow, 
+* Michael Fawcett, 
+* Ben FrantzDale, 
+* Ron Garcia,
+* David Greene,
+* Peder Holt,
+* Janek Kozicki, 
+* Andy Little,
+* Kevin Lynch,
+* Torsten Maehne
+* Noah Roberts,
+* Andrey Semashev,
+* David Walthall,
+* Deane Yang, 
+
+and all the members of the Boost mailing list who provided their input into 
+the design and implementation of this library.
+
+[endsect] [/section:Acknowledgements Acknowledgements]
+
+[section:HelpWanted Help Wanted]
+
+ Any help in the following areas would be much appreciated:
+
+* testing on other compilers and operating systems
+* performance testing on various architectures
+* tutorials 
+
+[endsect]
+
+[section:version_id Version Info]
+
+__boostroot
+
+Last edit to Quickbook file __FILENAME__ was at __TIME__ on __DATE__.
+
+[tip This should appear on the pdf version (but may be redundant on html).]
+[/ Useful on pdf version. See also Last revised timestamp on first page of html version.]
+[/See also Adobe Reader pdf File Properties for creation date, and PDF producer, version and page count.]
+
+[endsect] [/section:version_id Version Info]
+
+[section:ReleaseNotes Release Notes]
+
+1.2 (March 2010)
+
+* Added autoprefix ready for Boost 1.43
+
+1.0.0 (August 1, 2008) :
+
+* Initial release with Boost 1.36
+
+0.7.1 (March 14, 2007) :
+
+* Boost.Typeof emulation support.
+* attempting to rebind a heterogeneous_system to a different set of dimensions now fails.
+* cmath.hpp now works with como-win32.
+* minor changes to the tests and examples to make msvc 7.1 happy.
+
+0.7.0 (March 13, 2007) :
+
+* heterogeneous and mixed system functionality added.
+* added fine-grained implicit unit conversion on a per fundamental dimension basis.
+* added a number of utility metafunction classes and predicates.
+* [headerref boost/units/operators.hpp] now uses `BOOST_TYPEOF` when possible.
+* angular units added in [headerref boost/units/systems/angle/gradians.hpp]
+  and [headerref boost/units/systems/angle/gradians.hpp].
+  Implicit conversion of radians between trigonometric, SI, and CGS systems is allowed.
+* a variety of [___unit] and [___quantity] tests added.
+* examples now provide self-tests.
+
+0.6.2 (February 22, 2007) :
+
+*  changed template order in `unit` so dimension precedes unit system
+*  added `homogeneous_system<S>` for unit systems
+*  incorporated changes to [headerref boost/units/dimension.hpp] (compile-time sorting by predicate), 
+   [headerref boost/units/conversion.hpp] (thread-safe implementation of quantity conversions), 
+   and [headerref boost/units/io.hpp] (now works with any `std::basic_ostream`) by SW
+* added abstract units in [headerref boost/units/systems/abstract.hpp] to allow abstract dimensional
+  analysis
+* new example demonstrating implementation of code based on requirements from 
+  Michael Fawcett ([@../../libs/units/example/radar_beam_height.cpp radar_beam_height.cpp])
+
+0.6.1 (February 13, 2007) :
+
+* added metafunctions to test if a type is 
+    * a valid dimension list (`is_dimension_list<D>`)
+    * a unit (`is_unit<T>` and `is_unit_of_system<U,System>`)
+    * a quantity (`is_quantity<T>` and `is_quantity_of_system<Q,System>`) 
+* quantity conversion factor is now computed at compile time 
+* static constants now avoid ODR problems
+* unit_example_14.cpp now uses Boost.Timer
+* numerous minor fixes suggested by SW
+
+0.6.0 (February 8, 2007) :
+
+* incorporated Steven Watanabe's optimized code for dimension.hpp, leading to *dramatic*
+  decreases in compilation time (nearly a factor of 10 for unit_example_4.cpp in my tests).
+
+0.5.8 (February 7, 2007) :
+
+* fixed `#include` in [headerref boost/units/systems/si/base.hpp] (thanks to Michael Fawcett and 
+  Steven Watanabe)
+* removed references to obsolete `base_type` in [___unit_info] (thanks to Michael Fawcett)
+* moved functions in [headerref boost/units/cmath.hpp] into `boost::units` namespace 
+  (thanks to Steven Watanabe)
+* fixed `#include` guards to be consistently named `BOOST_UNITS_XXX` (thanks to Steven 
+  Watanabe)
+
+0.5.7 (February 5, 2007) :
+
+* changed quantity conversion helper to increase flexibility
+* minor documentation changes
+* submitted for formal review as a Boost library
+
+0.5.6 (January 22, 2007) :
+
+* added IEEE 1541 standard binary prefixes along with SI prefixes to and extended algebra of
+  `scale` and `scaled_value` classes (thanks to Kevin Lynch)
+* split SI units into separate header files to minimize the "kitchen sink" include problem
+  (thanks to Janek Kozicki)
+* added convenience classes for declaring fundamental dimensions and composite dimensions 
+   with integral powers (`fundamental_dimension` and `composite_dimension` respectively)
+
+0.5.5 (January 18, 2007) :
+
+* template parameter order in `quantity` switched and default `value_type` of `double` added
+  (thanks to Andrey Semashev and Paul Bristow)
+* added implicit `value_type` conversion where allowed (thanks to Andrey Semashev)
+* added `quantity_cast` for three cases (thanks to Andrey Semashev):
+    * constructing `quantity` from raw `value_type`
+    * casting from one `value_type` to another
+    * casting from one `unit` to another (where conversion is allowed) 
+* added` metre` and `metres` and related constants to the SI system for the convenience of
+  our Commonwealth friends...
+
+0.5.4 (January 12, 2007) :
+
+* completely reimplemented unit conversion to allow for arbitrary unit conversions
+  between systems
+* strict quantity construction is default; quantities can be constructed from bare values 
+  by using static member `from_value`
+
+0.5.3 (December 12, 2006) :
+
+* added Boost.Serialization support to `unit` and `quantity` classes
+* added option to enforce strict construction of quantities (only constructible
+  by multiplication of scalar by unit or quantity by unit) by preprocessor
+  `MCS_STRICT_QUANTITY_CONSTRUCTION` switch
+
+0.5.2 (December 4, 2006) :
+
+* added `<cmath>` wrappers in the `std` namespace for functions that can support quantities 
+
+0.5.1 (November 3, 2006) :
+
+* converted to Boost Software License
+* boostified directory structure and file paths
+
+0.5 (November 2, 2006) :
+
+* completely reimplemented SI and CGS unit systems and changed syntax for quantities
+* significantly streamlined `pow` and `root` so for most applications it is only
+  necessary to define `power_typeof_helper` and `root_typeof_helper` to gain this
+  functionality
+* added a selection of physical constants from the CODATA tables
+* added a skeleton `complex` class that correctly supports both `complex<quantity<Y,Unit> >`
+  and `quantity<complex<Y>,Unit>` as an example
+* investigate using Boost.Typeof for compilers that do not support `typeof`
+
+0.4 (October 13, 2006) : 
+
+* `pow<R>` and `root<R>` improved for user-defined types
+* added unary + and unary - operators
+* added new example of interfacing with `boost::math::quaternion`
+* added optional preprocessor switch to enable implicit unit conversions
+  (`BOOST_UNITS_ENABLE_IMPLICIT_UNIT_CONVERSIONS`) 
+
+0.3 (September 6, 2006) :
+
+* Support for `op(X x,Y y)` for g++ added. This is automatically
+  active when compiling with gcc and can be optionally enabled by defining the preprocessor
+  constant `BOOST_UNITS_HAS_TYPEOF`
+
+0.2 (September 4, 2006) : Second alpha release based on slightly modified code from 0.1 release
+
+0.1 (December 13, 2003)  : written as a Boost demonstration of MPL-based dimensional analysis
+in 2003.
+
+[endsect]
+
+[section:TODO TODO]
+
+* Document concepts
+* Implementation of I/O is rudimentary; consider methods of i18n using facets
+* Consider runtime variant, perhaps using overload like `quantity<runtime,Y>`
+
+[endsect] [/section:TODO TODO]
diff --git a/example/Jamfile.v2 b/example/Jamfile.v2
new file mode 100644
index 0000000..b918205
--- /dev/null
+++ b/example/Jamfile.v2
@@ -0,0 +1,25 @@
+# Jamfile.v2
+#
+# Copyright (c) 2007-2008
+# Steven Watanabe
+#
+# Distributed under the Boost Software License, Version 1.0. (See
+# accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt
+
+import testing ;
+import path ;
+
+project boost/units/example :
+  : requirements <include>$(BOOST_ROOT) <include>../../.. <warnings>all
+;
+
+files = [ path.glob . : *.cpp : performance.* runtime_unit.* ] ;
+
+for local file in $(files)
+{
+    run $(file) ;
+}
+
+compile performance.cpp ;
+run runtime_unit.cpp : <runtime_unit_input.txt ;
diff --git a/example/autoprefixes.cpp b/example/autoprefixes.cpp
new file mode 100644
index 0000000..9966766
--- /dev/null
+++ b/example/autoprefixes.cpp
@@ -0,0 +1,148 @@
+// Boost.Units - A C++ library for zero-overhead dimensional analysis and
+// unit/quantity manipulation and conversion
+//
+// Copyright (C) 2003-2008 Matthias Christian Schabel
+// Copyright (C) 2008 Steven Watanabe
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+/**
+\file
+
+\brief Example of using autoprefixes.
+
+\details
+Example of using engineering (10^3) and binary (2^10) autoprefixes.
+
+Output:
+@verbatim
+autoprefixes.cpp
+using native typeof
+Linking...
+Embedding manifest...
+Autorun "j:\Cpp\Misc\debug\autoprefixes.exe"
+2.345 m
+2.345 km
+5.49902 MJ
+5.49902 megajoule
+2.048 kb
+2 Kib
+2345.6
+23456
+2345.6
+23456
+m
+meter
+0
+1
+@endverbatim
+//[autoprefixes_output
+
+//] [/autoprefixes_output
+
+**/
+
+#include <iostream>
+
+#include <boost/units/io.hpp>
+#include <boost/units/pow.hpp>
+#include <boost/units/systems/si.hpp>
+#include <boost/units/systems/si/io.hpp>
+#include <boost/units/quantity.hpp>
+
+struct byte_base_unit : boost::units::base_unit<byte_base_unit, boost::units::dimensionless_type, 3>
+{
+  static constexpr const char* name() { return("byte"); }
+  static constexpr const char* symbol() { return("b"); }
+};
+
+struct thing_base_unit : boost::units::base_unit<thing_base_unit, boost::units::dimensionless_type, 4>
+{
+  static constexpr const char* name() { return("thing"); }
+  static constexpr const char* symbol() { return(""); }
+};
+
+struct euro_base_unit : boost::units::base_unit<euro_base_unit, boost::units::dimensionless_type, 5>
+{
+  static constexpr const char* name() { return("EUR"); }
+  static constexpr const char* symbol() { return("€"); }
+};
+
+int main()
+{
+  using std::cout;
+  using std::endl;
+
+  using namespace boost::units;
+  using namespace boost::units::si;
+
+ //[autoprefixes_snippet_1
+  using boost::units::binary_prefix;
+  using boost::units::engineering_prefix;
+  using boost::units::no_prefix;
+
+  quantity<length> l = 2.345 * meters;   // A quantity of length, in units of meters.
+  cout << engineering_prefix << l << endl; // Outputs "2.345 m".
+  l =  1000.0 * l; // Increase it by 1000, so expect a k prefix.
+  // Note that a double 1000.0 is required - an integer will fail to compile.
+  cout << engineering_prefix << l << endl; // Output autoprefixed with k to "2.345 km".
+
+  quantity<energy> e = kilograms * pow<2>(l / seconds); // A quantity of energy.
+  cout << engineering_prefix << e << endl; // 5.49902 MJ
+  cout << name_format << engineering_prefix << e << endl; // 5.49902 megaJoule
+  //] [/autoprefixes_snippet_1]
+
+  //[autoprefixes_snippet_2
+  // Don't forget that the units name or symbol format specification is persistent.
+  cout << symbol_format << endl; // Resets the format to the default symbol format.
+
+  quantity<byte_base_unit::unit_type> b = 2048. * byte_base_unit::unit_type();
+  cout << engineering_prefix << b << endl;  // 2.048 kb
+  cout << symbol_format << binary_prefix << b << endl; //  "2 Kib"
+  //] [/autoprefixes_snippet_2]
+
+  // Note that scalar dimensionless values are *not* prefixed automatically by the engineering_prefix or binary_prefix iostream manipulators.
+  //[autoprefixes_snippet_3
+  const double s1 = 2345.6;
+  const long x1 = 23456;
+  cout << engineering_prefix << s1 << endl; // 2345.6
+  cout << engineering_prefix << x1 << endl; // 23456
+
+  cout << binary_prefix << s1 << endl; // 2345.6
+  cout << binary_prefix << x1 << endl; // 23456
+  //] [/autoprefixes_snippet_3]
+
+  //[autoprefixes_snippet_4
+  const length L; // A unit of length (but not a quantity of length).
+  cout << L << endl; // Default length unit is meter,
+  // but default is symbol format so output is just "m".
+  cout << name_format << L << endl; // default length name is "meter".
+  //] [/autoprefixes_snippet_4]
+
+  //[autoprefixes_snippet_5
+  no_prefix(cout); // Clear any prefix flag.
+  cout << no_prefix << endl; // Clear any prefix flag using `no_prefix` manipulator.
+  //] [/autoprefixes_snippet_5]
+
+  //[autoprefixes_snippet_6
+  cout << boost::units::get_autoprefix(cout) << endl; // 8 is `autoprefix_binary` from `enum autoprefix_mode`.
+  cout << boost::units::get_format(cout) << endl; // 1 is `name_fmt` from `enum format_mode`.
+  //] [/autoprefixes_snippet_6]
+
+
+  quantity<thing_base_unit::unit_type> t = 2048. * thing_base_unit::unit_type();
+  cout << name_format << engineering_prefix << t << endl;  // 2.048 kilothing
+  cout << symbol_format << engineering_prefix << t << endl;  // 2.048 k
+
+  cout  << binary_prefix << t << endl; //  "2 Ki"
+
+  quantity<euro_base_unit::unit_type> ce = 2048. * euro_base_unit::unit_type();
+  cout << name_format << engineering_prefix << ce << endl;  // 2.048 kiloEUR
+  cout << symbol_format << engineering_prefix << ce << endl;  // 2.048 k€
+
+
+    return 0;
+} // int main()
+
diff --git a/example/complex.cpp b/example/complex.cpp
new file mode 100644
index 0000000..d3579a0
--- /dev/null
+++ b/example/complex.cpp
@@ -0,0 +1,421 @@
+// Boost.Units - A C++ library for zero-overhead dimensional analysis and 
+// unit/quantity manipulation and conversion
+//
+// Copyright (C) 2003-2008 Matthias Christian Schabel
+// Copyright (C) 2008 Steven Watanabe
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+/** 
+\file
+    
+\brief complex.cpp
+
+\details
+Demonstrate a complex number class that functions correctly with quantities.
+
+Output:
+@verbatim
+
+//[complex_output_1
++L      = 2 + 1 i m
+-L      = -2 + -1 i m
+L+L     = 4 + 2 i m
+L-L     = 0 + 0 i m
+L*L     = 3 + 4 i m^2
+L/L     = 1 + 0 i dimensionless
+L^3     = 2 + 11 i m^3
+L^(3/2) = 2.56713 + 2.14247 i m^(3/2)
+3vL     = 1.29207 + 0.201294 i m^(1/3)
+(3/2)vL = 1.62894 + 0.520175 i m^(2/3)
+//]
+
+//[complex_output_2
++L      = 2 m + 1 m i
+-L      = -2 m + -1 m i
+L+L     = 4 m + 2 m i
+L-L     = 0 m + 0 m i
+L*L     = 3 m^2 + 4 m^2 i
+L/L     = 1 dimensionless + 0 dimensionless i
+L^3     = 2 m^3 + 11 m^3 i
+L^(3/2) = 2.56713 m^(3/2) + 2.14247 m^(3/2) i
+3vL     = 1.29207 m^(1/3) + 0.201294 m^(1/3) i
+(3/2)vL = 1.62894 m^(2/3) + 0.520175 m^(2/3) i
+//]
+
+@endverbatim
+**/
+
+#include <cmath>
+#include <complex>
+#include <iostream>
+
+#include <boost/mpl/list.hpp>
+
+#include <boost/units/io.hpp>
+#include <boost/units/pow.hpp>
+#include <boost/units/quantity.hpp>
+
+#include "test_system.hpp"
+
+//[complex_class_snippet_1
+namespace boost {
+
+namespace units {
+
+/// replacement complex class 
+template<class T>
+class complex
+{
+    public:
+        typedef complex<T>  this_type;
+        
+        constexpr complex(const T& r = 0,const T& i = 0) : r_(r),i_(i) { }
+        constexpr complex(const this_type& source) : r_(source.r_),i_(source.i_) { }
+        
+        constexpr this_type& operator=(const this_type& source)
+        {
+            if (this == &source) return *this;
+            
+            r_ = source.r_;
+            i_ = source.i_;
+            
+            return *this;
+        }
+        
+        constexpr T& real()             { return r_; }
+        constexpr T& imag()             { return i_; }
+        
+        constexpr const T& real() const       { return r_; }
+        constexpr const T& imag() const       { return i_; }
+
+        constexpr this_type& operator+=(const T& val)
+        {
+            r_ += val;
+            return *this;
+        }
+        
+        constexpr this_type& operator-=(const T& val)
+        {
+            r_ -= val;
+            return *this;
+        }
+        
+        constexpr this_type& operator*=(const T& val)
+        {
+            r_ *= val;
+            i_ *= val;
+            return *this;
+        }
+        
+        constexpr this_type& operator/=(const T& val)
+        {
+            r_ /= val;
+            i_ /= val;
+            return *this;
+        }
+        
+        constexpr this_type& operator+=(const this_type& source)
+        {
+            r_ += source.r_;
+            i_ += source.i_;
+            return *this;
+        }
+        
+        constexpr this_type& operator-=(const this_type& source)
+        {
+            r_ -= source.r_;
+            i_ -= source.i_;
+            return *this;
+        }
+        
+        constexpr this_type& operator*=(const this_type& source)
+        {
+            *this = *this * source;
+            return *this;
+        }
+        
+        constexpr this_type& operator/=(const this_type& source)
+        {
+            *this = *this / source;
+            return *this;
+        }
+        
+    private:
+        T   r_,i_;
+};
+
+}
+
+}
+
+#if BOOST_UNITS_HAS_BOOST_TYPEOF
+
+#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
+
+BOOST_TYPEOF_REGISTER_TEMPLATE(boost::units::complex, 1)
+
+#endif
+
+namespace boost {
+
+namespace units {
+
+template<class X>
+constexpr
+complex<typename unary_plus_typeof_helper<X>::type>
+operator+(const complex<X>& x)
+{
+    typedef typename unary_plus_typeof_helper<X>::type  type;
+    
+    return complex<type>(x.real(),x.imag());
+}
+
+template<class X>
+constexpr
+complex<typename unary_minus_typeof_helper<X>::type>
+operator-(const complex<X>& x)
+{
+    typedef typename unary_minus_typeof_helper<X>::type type;
+    
+    return complex<type>(-x.real(),-x.imag());
+}
+
+template<class X,class Y>
+constexpr
+complex<typename add_typeof_helper<X,Y>::type>
+operator+(const complex<X>& x,const complex<Y>& y)
+{
+    typedef typename boost::units::add_typeof_helper<X,Y>::type type;
+    
+    return complex<type>(x.real()+y.real(),x.imag()+y.imag());
+}
+
+template<class X,class Y>
+constexpr
+complex<typename boost::units::subtract_typeof_helper<X,Y>::type>
+operator-(const complex<X>& x,const complex<Y>& y)
+{
+    typedef typename boost::units::subtract_typeof_helper<X,Y>::type    type;
+    
+    return complex<type>(x.real()-y.real(),x.imag()-y.imag());
+}
+
+template<class X,class Y>
+constexpr
+complex<typename boost::units::multiply_typeof_helper<X,Y>::type>
+operator*(const complex<X>& x,const complex<Y>& y)
+{
+    typedef typename boost::units::multiply_typeof_helper<X,Y>::type    type;
+    
+    return complex<type>(x.real()*y.real() - x.imag()*y.imag(),
+                         x.real()*y.imag() + x.imag()*y.real());
+
+//  fully correct implementation has more complex return type
+//
+//    typedef typename boost::units::multiply_typeof_helper<X,Y>::type xy_type;
+//    
+//    typedef typename boost::units::add_typeof_helper<
+//      xy_type,xy_type>::type         xy_plus_xy_type;
+//    typedef typename
+//        boost::units::subtract_typeof_helper<xy_type,xy_type>::type
+//        xy_minus_xy_type;
+//    
+//    BOOST_STATIC_ASSERT((boost::is_same<xy_plus_xy_type,
+//                                       xy_minus_xy_type>::value == true));
+//    
+//    return complex<xy_plus_xy_type>(x.real()*y.real()-x.imag()*y.imag(),
+//                                    x.real()*y.imag()+x.imag()*y.real());
+}
+
+template<class X,class Y>
+constexpr
+complex<typename boost::units::divide_typeof_helper<X,Y>::type>
+operator/(const complex<X>& x,const complex<Y>& y)
+{
+    // naive implementation of complex division
+    typedef typename boost::units::divide_typeof_helper<X,Y>::type type;
+
+    return complex<type>((x.real()*y.real()+x.imag()*y.imag())/
+                            (y.real()*y.real()+y.imag()*y.imag()),
+                         (x.imag()*y.real()-x.real()*y.imag())/
+                            (y.real()*y.real()+y.imag()*y.imag()));
+                         
+//  fully correct implementation has more complex return type
+//
+//  typedef typename boost::units::multiply_typeof_helper<X,Y>::type xy_type;
+//  typedef typename boost::units::multiply_typeof_helper<Y,Y>::type yy_type;
+//
+//  typedef typename boost::units::add_typeof_helper<xy_type, xy_type>::type
+//      xy_plus_xy_type;
+//  typedef typename boost::units::subtract_typeof_helper<
+//      xy_type,xy_type>::type xy_minus_xy_type;
+//
+//  typedef typename boost::units::divide_typeof_helper<
+//      xy_plus_xy_type,yy_type>::type      xy_plus_xy_over_yy_type;
+//  typedef typename boost::units::divide_typeof_helper<
+//      xy_minus_xy_type,yy_type>::type     xy_minus_xy_over_yy_type;
+//
+//  BOOST_STATIC_ASSERT((boost::is_same<xy_plus_xy_over_yy_type,
+//                                  xy_minus_xy_over_yy_type>::value == true));
+//
+//  return complex<xy_plus_xy_over_yy_type>(
+//      (x.real()*y.real()+x.imag()*y.imag())/
+//          (y.real()*y.real()+y.imag()*y.imag()),
+//      (x.imag()*y.real()-x.real()*y.imag())/
+//          (y.real()*y.real()+y.imag()*y.imag()));
+}
+
+template<class Y>
+complex<Y> 
+pow(const complex<Y>& x,const Y& y)
+{
+    std::complex<Y> tmp(x.real(),x.imag());
+    
+    tmp = std::pow(tmp,y);
+    
+    return complex<Y>(tmp.real(),tmp.imag());
+}
+
+template<class Y>
+std::ostream& operator<<(std::ostream& os,const complex<Y>& val)
+{
+    os << val.real() << " + " << val.imag() << " i";
+
+    return os;
+}
+
+/// specialize power typeof helper for complex<Y>
+template<class Y,long N,long D> 
+struct power_typeof_helper<complex<Y>,static_rational<N,D> >                
+{ 
+    typedef complex<
+        typename power_typeof_helper<Y,static_rational<N,D> >::type
+    > type; 
+    
+    static type value(const complex<Y>& x)  
+    { 
+        const static_rational<N,D>  rat;
+
+        const Y    m = Y(rat.numerator())/Y(rat.denominator());
+        
+        return boost::units::pow(x,m);
+    }
+};
+
+/// specialize root typeof helper for complex<Y>
+template<class Y,long N,long D> 
+struct root_typeof_helper<complex<Y>,static_rational<N,D> >                
+{ 
+    typedef complex<
+        typename root_typeof_helper<Y,static_rational<N,D> >::type
+    > type; 
+    
+    static type value(const complex<Y>& x)  
+    { 
+        const static_rational<N,D>  rat;
+
+        const Y    m = Y(rat.denominator())/Y(rat.numerator());
+        
+        return boost::units::pow(x,m);
+    }
+};
+
+/// specialize power typeof helper for complex<quantity<Unit,Y> >
+template<class Y,class Unit,long N,long D> 
+struct power_typeof_helper<complex<quantity<Unit,Y> >,static_rational<N,D> >
+{ 
+    typedef typename
+        power_typeof_helper<Y,static_rational<N,D> >::type       value_type;
+    typedef typename
+        power_typeof_helper<Unit,static_rational<N,D> >::type    unit_type;
+    typedef quantity<unit_type,value_type>                      quantity_type;
+    typedef complex<quantity_type>                              type; 
+    
+    static type value(const complex<quantity<Unit,Y> >& x)  
+    { 
+        const complex<value_type>   tmp =
+            pow<static_rational<N,D> >(complex<Y>(x.real().value(),
+                                                  x.imag().value()));
+        
+        return type(quantity_type::from_value(tmp.real()),
+                    quantity_type::from_value(tmp.imag()));
+    }
+};
+
+/// specialize root typeof helper for complex<quantity<Unit,Y> >
+template<class Y,class Unit,long N,long D> 
+struct root_typeof_helper<complex<quantity<Unit,Y> >,static_rational<N,D> >
+{ 
+    typedef typename
+        root_typeof_helper<Y,static_rational<N,D> >::type       value_type;
+    typedef typename
+        root_typeof_helper<Unit,static_rational<N,D> >::type    unit_type;
+    typedef quantity<unit_type,value_type>                      quantity_type;
+    typedef complex<quantity_type>                              type; 
+    
+    static type value(const complex<quantity<Unit,Y> >& x)  
+    { 
+        const complex<value_type>   tmp =
+            root<static_rational<N,D> >(complex<Y>(x.real().value(),
+                                                   x.imag().value()));
+        
+        return type(quantity_type::from_value(tmp.real()),
+                   quantity_type::from_value(tmp.imag()));
+    }
+};
+
+} // namespace units
+
+} // namespace boost
+//]
+
+int main(void)
+{
+    using namespace boost::units;
+    using namespace boost::units::test;
+    
+    {
+    //[complex_snippet_1
+    typedef quantity<length,complex<double> >     length_dimension;
+        
+    const length_dimension    L(complex<double>(2.0,1.0)*meters);
+    //]
+    
+    std::cout << "+L      = " << +L << std::endl
+              << "-L      = " << -L << std::endl
+              << "L+L     = " << L+L << std::endl
+              << "L-L     = " << L-L << std::endl
+              << "L*L     = " << L*L << std::endl
+              << "L/L     = " << L/L << std::endl
+              << "L^3     = " << pow<3>(L) << std::endl
+              << "L^(3/2) = " << pow< static_rational<3,2> >(L) << std::endl
+              << "3vL     = " << root<3>(L) << std::endl
+              << "(3/2)vL = " << root< static_rational<3,2> >(L) << std::endl
+              << std::endl;
+    }
+    
+    {
+    //[complex_snippet_2
+    typedef complex<quantity<length> >     length_dimension;
+        
+    const length_dimension    L(2.0*meters,1.0*meters);
+    //]
+    
+    std::cout << "+L      = " << +L << std::endl
+              << "-L      = " << -L << std::endl
+              << "L+L     = " << L+L << std::endl
+              << "L-L     = " << L-L << std::endl
+              << "L*L     = " << L*L << std::endl
+              << "L/L     = " << L/L << std::endl
+              << "L^3     = " << pow<3>(L) << std::endl
+              << "L^(3/2) = " << pow< static_rational<3,2> >(L) << std::endl
+              << "3vL     = " << root<3>(L) << std::endl
+              << "(3/2)vL = " << root< static_rational<3,2> >(L) << std::endl
+              << std::endl;
+    }
+
+    return 0;
+}
diff --git a/example/composite_output.cpp b/example/composite_output.cpp
new file mode 100644
index 0000000..022ea4e
--- /dev/null
+++ b/example/composite_output.cpp
@@ -0,0 +1,116 @@
+// Boost.Units - A C++ library for zero-overhead dimensional analysis and 
+// unit/quantity manipulation and conversion
+//
+// Copyright (C) 2003-2008 Matthias Christian Schabel
+// Copyright (C) 2008 Steven Watanabe
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+/** 
+\file
+    
+\brief composite_output.cpp
+
+\details An example of textual representations of units.
+
+Output:
+@verbatim
+
+//[conversion_output_output
+2 dyn
+2 dyn
+2 dyne
+cm g s^-1
+centimeter gram second^-1
+dyn
+dyne
+n
+nano
+n
+nano
+F
+farad
+1 F
+1 farad
+nF
+nanofarad
+1 nF
+1 nanofarad
+n(cm g s^-1)
+nano(centimeter gram second^-1)
+//]
+
+@endverbatim
+**/
+#include <boost/units/quantity.hpp>
+#include <boost/units/systems/cgs.hpp>
+#include <boost/units/io.hpp>
+#include <boost/units/scale.hpp>
+
+#include <boost/units/detail/utility.hpp>
+
+#include <boost/units/systems/si/capacitance.hpp>
+#include <boost/units/systems/si/io.hpp>
+#include <boost/units/systems/si/prefixes.hpp>
+
+#include <iostream>
+#include <sstream>
+
+namespace boost {
+
+namespace units {
+
+//[composite_output_snippet_1
+
+std::string name_string(const cgs::force&)
+{
+    return "dyne";
+}
+
+std::string symbol_string(const cgs::force&)
+{
+    return "dyn";
+}
+
+//]
+
+}
+
+}
+
+int main() 
+{
+    using namespace boost::units;
+    using boost::units::cgs::centimeter;
+    using boost::units::cgs::gram;
+    using boost::units::cgs::second;
+    using boost::units::cgs::dyne;
+        
+    //[composite_output_snippet_2]
+    std::cout << 2.0 * dyne << std::endl
+              << symbol_format << 2.0 * dyne << std::endl
+              << name_format << 2.0 * dyne << std::endl
+              << symbol_format << gram*centimeter/second << std::endl
+              << name_format << gram*centimeter/second << std::endl
+              << symbol_format << gram*centimeter/(second*second) << std::endl
+              << name_format << gram*centimeter/(second*second) << std::endl
+              << symbol_string(scale<10,static_rational<-9> >()) << std::endl
+              << name_string(scale<10,static_rational<-9> >()) << std::endl
+              << symbol_format << si::nano << std::endl
+              << name_format << si::nano << std::endl
+              << symbol_format << si::farad << std::endl
+              << name_format << si::farad << std::endl
+              << symbol_format << 1.0*si::farad << std::endl
+              << name_format << 1.0*si::farad << std::endl
+              << symbol_format << si::farad*si::nano << std::endl
+              << name_format << si::farad*si::nano << std::endl
+              << symbol_format << 1.0*si::farad*si::nano << std::endl
+              << name_format << 1.0*si::farad*si::nano << std::endl
+              << symbol_format << si::nano*gram*centimeter/second << std::endl
+              << name_format << si::nano*gram*centimeter/second << std::endl;
+    //]
+              
+    return 0;
+}
diff --git a/example/conversion.cpp b/example/conversion.cpp
new file mode 100644
index 0000000..0299dfd
--- /dev/null
+++ b/example/conversion.cpp
@@ -0,0 +1,124 @@
+// Boost.Units - A C++ library for zero-overhead dimensional analysis and 
+// unit/quantity manipulation and conversion
+//
+// Copyright (C) 2003-2008 Matthias Christian Schabel
+// Copyright (C) 2008 Steven Watanabe
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+/** 
+\file
+    
+\brief conversion.cpp
+
+\details
+Test explicit and implicit unit conversion.
+
+Output:
+@verbatim
+
+//[conversion_output_1
+L1 = 2 m
+L2 = 2 m
+L3 = 2 m
+L4 = 200 cm
+L5 = 5 m
+L6 = 4 m
+L7 = 200 cm
+//]
+
+//[conversion_output_2
+volume (m^3)  = 1 m^3
+volume (cm^3) = 1e+06 cm^3
+volume (m^3)  = 1 m^3
+
+energy (joules) = 1 J
+energy (ergs)   = 1e+07 erg
+energy (joules) = 1 J
+
+velocity (2 m/s)  = 2 m s^-1
+velocity (2 cm/s) = 0.02 m s^-1
+//]
+
+@endverbatim
+**/
+
+#include <iostream>
+
+#include <boost/units/io.hpp>
+#include <boost/units/pow.hpp>
+#include <boost/units/systems/cgs.hpp>
+#include <boost/units/systems/cgs/io.hpp>
+#include <boost/units/systems/si.hpp>
+#include <boost/units/systems/si/io.hpp>
+
+using namespace boost::units;
+
+int main()
+{
+    // test quantity_cast
+    {
+    // implicit value_type conversions
+    //[conversion_snippet_1
+    quantity<si::length>     L1 = quantity<si::length,int>(int(2.5)*si::meters);
+    quantity<si::length,int> L2(quantity<si::length,double>(2.5*si::meters));
+    //]
+    
+    //[conversion_snippet_3
+    quantity<si::length,int> L3 = static_cast<quantity<si::length,int> >(L1);
+    //]
+    
+    //[conversion_snippet_4
+    quantity<cgs::length>    L4 = static_cast<quantity<cgs::length> >(L1);
+    //]
+    
+    quantity<si::length,int> L5(4*si::meters),
+                             L6(5*si::meters);
+    quantity<cgs::length>    L7(L1);
+    
+    swap(L5,L6);
+    
+    std::cout << "L1 = " << L1 << std::endl
+              << "L2 = " << L2 << std::endl
+              << "L3 = " << L3 << std::endl
+              << "L4 = " << L4 << std::endl
+              << "L5 = " << L5 << std::endl
+              << "L6 = " << L6 << std::endl
+              << "L7 = " << L7 << std::endl
+              << std::endl;
+    }
+    
+    // test explicit unit system conversion
+    {
+    //[conversion_snippet_5
+    quantity<si::volume>    vs(1.0*pow<3>(si::meter));      
+    quantity<cgs::volume>   vc(vs);
+    quantity<si::volume>    vs2(vc);
+                        
+    quantity<si::energy>    es(1.0*si::joule);      
+    quantity<cgs::energy>   ec(es);
+    quantity<si::energy>    es2(ec);
+                        
+    quantity<si::velocity>  v1 = 2.0*si::meters/si::second,     
+                            v2(2.0*cgs::centimeters/cgs::second);
+    //]
+    
+    std::cout << "volume (m^3)  = " << vs << std::endl
+              << "volume (cm^3) = " << vc << std::endl
+              << "volume (m^3)  = " << vs2 << std::endl
+              << std::endl;
+            
+    std::cout << "energy (joules) = " << es << std::endl
+              << "energy (ergs)   = " << ec << std::endl
+              << "energy (joules) = " << es2 << std::endl
+              << std::endl;
+            
+    std::cout << "velocity (2 m/s)  = " << v1 << std::endl
+              << "velocity (2 cm/s) = " << v2 << std::endl
+              << std::endl;
+    }
+
+    return 0;
+}
diff --git a/example/conversion_factor.cpp b/example/conversion_factor.cpp
new file mode 100644
index 0000000..4401e47
--- /dev/null
+++ b/example/conversion_factor.cpp
@@ -0,0 +1,76 @@
+// Boost.Units - A C++ library for zero-overhead dimensional analysis and 
+// unit/quantity manipulation and conversion
+//
+// Copyright (C) 2003-2008 Matthias Christian Schabel
+// Copyright (C) 2008 Steven Watanabe
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+/** 
+\file
+    
+\brief conversion_factor.cpp
+
+\details An example of using conversion_factor.
+
+Output:
+@verbatim
+
+//[conversion_factor_output
+1e-005
+100
+1e-005
+100
+0.01
+//]
+
+@endverbatim
+**/
+
+#include <iostream>
+
+#include <boost/units/cmath.hpp>
+#include <boost/units/io.hpp>
+#include <boost/units/quantity.hpp>
+#include <boost/units/systems/cgs/acceleration.hpp>
+#include <boost/units/systems/si/acceleration.hpp>
+#include <boost/units/systems/si/force.hpp>
+#include <boost/units/systems/cgs/force.hpp>
+#include <boost/units/systems/si/mass.hpp>
+#include <boost/units/systems/cgs/mass.hpp>
+#include <boost/units/systems/si/momentum.hpp>
+#include <boost/units/systems/cgs/momentum.hpp>
+
+int main()
+{
+    using namespace boost;
+    using namespace boost::units;
+
+    //[conversion_factor_snippet_1
+    
+    double dyne_to_newton =
+        conversion_factor(cgs::dyne,si::newton);
+    std::cout << dyne_to_newton << std::endl;
+
+    double force_over_mass_conversion =
+        conversion_factor(si::newton/si::kilogram,cgs::dyne/cgs::gram);
+    std::cout << force_over_mass_conversion << std::endl;
+
+    double momentum_conversion =
+        conversion_factor(cgs::momentum(),si::momentum());
+    std::cout << momentum_conversion << std::endl;
+
+    double momentum_over_mass_conversion =
+        conversion_factor(si::momentum()/si::mass(),cgs::momentum()/cgs::gram);
+    std::cout << momentum_over_mass_conversion << std::endl;
+
+    double acceleration_conversion =
+        conversion_factor(cgs::gal,si::meter_per_second_squared);
+    std::cout << acceleration_conversion << std::endl;
+    
+    //]
+
+    return 0;
+}
diff --git a/example/dimension.cpp b/example/dimension.cpp
new file mode 100644
index 0000000..7f7ffb6
--- /dev/null
+++ b/example/dimension.cpp
@@ -0,0 +1,117 @@
+// Boost.Units - A C++ library for zero-overhead dimensional analysis and 
+// unit/quantity manipulation and conversion
+//
+// Copyright (C) 2003-2008 Matthias Christian Schabel
+// Copyright (C) 2008 Steven Watanabe
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+/** 
+\file
+    
+\brief dimension.cpp
+
+\details
+Test dimension list manipulation.
+
+Output:
+@verbatim
+
+//[dimension_output
+length_dimension  = list<dim<length_base_dimension, static_rational<1l, 1l> >, dimensionless_type>
+mass_dimension    = list<dim<mass_base_dimension, static_rational<1l, 1l> >, dimensionless_type>
+time_dimension    = list<dim<time_base_dimension, static_rational<1l, 1l> >, dimensionless_type>
+energy_dimension  = list<dim<length_base_dimension, static_rational<2l, 1l> >, list<dim<mass_base_dimension, static_rational<1l, 1l> >, list<dim<time_base_dimension, static_rational<-2l, 1l> >, dimensionless_type> > >
+LM_type      = list<dim<length_base_dimension, static_rational<1l, 1l> >, list<dim<mass_base_dimension, static_rational<1l, 1l> >, dimensionless_type> >
+L_T_type     = list<dim<length_base_dimension, static_rational<1l, 1l> >, list<dim<time_base_dimension, static_rational<-1l, 1l> >, dimensionless_type> >
+V_type       = list<dim<length_base_dimension, static_rational<1l, 1l> >, list<dim<time_base_dimension, static_rational<-1l, 1l> >, dimensionless_type> >
+//]
+
+@endverbatim
+**/
+
+#include <boost/type_traits/is_same.hpp>
+#include <boost/mpl/assert.hpp>
+
+#include <iostream>
+
+#include <boost/units/detail/utility.hpp>
+
+#include "test_system.hpp"
+
+namespace mpl = boost::mpl;
+
+int main(void)
+{   
+    using namespace boost::units;
+
+    BOOST_MPL_ASSERT((boost::is_same<
+        length_dimension,
+        mpl::push_front<
+            dimensionless_type,
+            dim<length_base_dimension, static_rational<1L, 1L> >
+        >::type
+    >));
+    BOOST_MPL_ASSERT((boost::is_same<
+        mass_dimension,
+        mpl::push_front<
+            dimensionless_type,
+            dim<mass_base_dimension, static_rational<1L, 1L> >
+        >::type
+    >));
+    BOOST_MPL_ASSERT((boost::is_same<energy_dimension, 
+        mpl::push_front<
+        mpl::push_front<
+        mpl::push_front<
+        dimensionless_type,
+        dim<time_base_dimension, static_rational<-2L, 1L> > >::type,
+        dim<mass_base_dimension, static_rational<1L, 1L> > >::type,
+        dim<length_base_dimension, static_rational<2L, 1L> > >::type>));
+                              
+    std::cout << "length_dimension  = "
+              << simplify_typename(length_dimension()) << std::endl
+              << "mass_dimension    = "
+              << simplify_typename(mass_dimension()) << std::endl
+              << "time_dimension    = "
+              << simplify_typename(time_dimension()) << std::endl
+              << "energy_dimension  = "
+              << simplify_typename(energy_dimension()) << std::endl;
+                  
+    //[dimension_snippet_1
+    typedef mpl::times<length_dimension,mass_dimension>::type   LM_type;
+    typedef mpl::divides<length_dimension,time_dimension>::type L_T_type;
+    typedef static_root<
+        mpl::divides<energy_dimension,mass_dimension>::type,
+        static_rational<2>
+    >::type    V_type;
+    //]
+    
+    BOOST_MPL_ASSERT((boost::is_same<LM_type, 
+        mpl::push_front<
+        mpl::push_front<
+        dimensionless_type,
+        dim<mass_base_dimension, static_rational<1L, 1L> > >::type,
+        dim<length_base_dimension, static_rational<1L, 1L> > >::type>));
+
+    BOOST_MPL_ASSERT((boost::is_same<L_T_type, 
+        mpl::push_front<
+        mpl::push_front<
+        dimensionless_type,
+        dim<time_base_dimension, static_rational<-1L, 1L> > >::type,
+        dim<length_base_dimension, static_rational<1L, 1L> > >::type>));
+
+    BOOST_MPL_ASSERT((boost::is_same<V_type, 
+        mpl::push_front<
+        mpl::push_front<
+        dimensionless_type,
+        dim<time_base_dimension, static_rational<-1L, 1L> > >::type,
+        dim<length_base_dimension, static_rational<1L, 1L> > >::type>));
+    
+    std::cout << "LM_type      = " << simplify_typename(LM_type()) << std::endl
+              << "L_T_type     = " << simplify_typename(L_T_type()) << std::endl
+              << "V_type       = " << simplify_typename(V_type()) << std::endl;
+              
+    return 0;
+}
diff --git a/example/heterogeneous_unit.cpp b/example/heterogeneous_unit.cpp
new file mode 100644
index 0000000..7a4f112
--- /dev/null
+++ b/example/heterogeneous_unit.cpp
@@ -0,0 +1,87 @@
+// Boost.Units - A C++ library for zero-overhead dimensional analysis and 
+// unit/quantity manipulation and conversion
+//
+// Copyright (C) 2003-2008 Matthias Christian Schabel
+// Copyright (C) 2008 Steven Watanabe
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+/** 
+\file
+    
+\brief heterogeneous_unit.cpp
+
+\details
+Test heterogeneous units and quantities.
+
+Output:
+@verbatim
+
+//[heterogeneous_unit_output_1
+1.5 m
+1 g
+1.5 m g
+1.5 m g^-1
+
+1 N
+1 kg s^-2
+
+1 cm kg s^-2
+1 cm m^-1 kg s^-2
+//]
+
+//[heterogeneous_unit_output_2
+1.5 cm m
+0.015 m^2
+//]
+
+@endverbatim
+**/
+
+#define MCS_USE_DEMANGLING
+//#define MCS_USE_BOOST_REGEX_DEMANGLING
+
+#include <iostream>
+
+#include <boost/units/io.hpp>
+#include <boost/units/pow.hpp>
+#include <boost/units/detail/utility.hpp>
+#include <boost/units/systems/cgs.hpp>
+#include <boost/units/systems/si.hpp>
+#include <boost/units/systems/si/io.hpp>
+
+using namespace boost::units;
+
+int main()
+{
+    //[heterogeneous_unit_snippet_1
+    quantity<si::length>        L(1.5*si::meter);
+    quantity<cgs::mass>         M(1.0*cgs::gram);
+    
+    std::cout << L << std::endl
+              << M << std::endl
+              << L*M << std::endl
+              << L/M << std::endl
+              << std::endl;
+              
+    std::cout << 1.0*si::meter*si::kilogram/pow<2>(si::second) << std::endl
+              << 1.0*si::meter*si::kilogram/pow<2>(si::second)/si::meter
+              << std::endl << std::endl;
+
+    std::cout << 1.0*cgs::centimeter*si::kilogram/pow<2>(si::second) << std::endl
+              << 1.0*cgs::centimeter*si::kilogram/pow<2>(si::second)/si::meter
+              << std::endl << std::endl;
+    //]
+    
+    //[heterogeneous_unit_snippet_2
+    quantity<si::area>      A(1.5*si::meter*cgs::centimeter);
+    
+    std::cout << 1.5*si::meter*cgs::centimeter << std::endl
+              << A << std::endl
+              << std::endl;
+    //]
+
+    return 0;
+}
diff --git a/example/information.cpp b/example/information.cpp
new file mode 100644
index 0000000..21ae3f9
--- /dev/null
+++ b/example/information.cpp
@@ -0,0 +1,100 @@
+// Boost.Units - A C++ library for zero-overhead dimensional analysis and 
+// unit/quantity manipulation and conversion
+//
+// Copyright (C) 2014 Erik Erlandson
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+//#include <boost/units/systems/information.hpp>
+
+/** 
+\file
+
+\brief information.cpp
+
+\details
+Demonstrate information unit system.
+
+Output:
+@verbatim
+bytes= 1.25e+08 B
+bits= 8e+06 b
+nats= 4605.17 nat
+1024 bytes in a kibi-byte
+8.38861e+06 bits in a mebi-byte
+0.000434294 hartleys in a milli-nat
+entropy in bits= 1 b
+entropy in nats= 0.693147 nat
+entropy in hartleys= 0.30103 Hart
+entropy in shannons= 1 Sh
+entropy in bytes= 0.125 B
+@endverbatim
+**/
+
+#include <cmath>
+#include <iostream>
+using std::cout;
+using std::endl;
+using std::log;
+
+#include <boost/units/quantity.hpp>
+#include <boost/units/io.hpp>
+#include <boost/units/conversion.hpp>
+namespace bu = boost::units;
+using bu::quantity;
+using bu::conversion_factor;
+
+// SI prefixes
+#include <boost/units/systems/si/prefixes.hpp>
+namespace si = boost::units::si;
+
+// information unit system
+#include <boost/units/systems/information.hpp>
+using namespace bu::information;
+
+// Define a function for the entropy of a bernoulli trial.
+// The formula is computed using natural log, so the units are in nats.
+// The user provides the desired return unit, the only restriction being that it
+// must be a unit of information.  Conversion to the requested return unit is 
+// accomplished automatically by the boost::units library.
+template <typename Sys>
+constexpr
+quantity<bu::unit<bu::information_dimension, Sys> > 
+bernoulli_entropy(double p, const bu::unit<bu::information_dimension, Sys>&) {
+    typedef bu::unit<bu::information_dimension, Sys> requested_unit;
+    return quantity<requested_unit>((-(p*log(p) + (1-p)*log(1-p)))*nats);
+}
+
+int main(int argc, char** argv) {
+    // a quantity of information (default in units of bytes) 
+    quantity<info> nbytes(1 * si::giga * bit);
+    cout << "bytes= " << nbytes << endl;
+
+    // a quantity of information, stored as bits
+    quantity<hu::bit::info> nbits(1 * si::mega * byte);
+    cout << "bits= " << nbits << endl;
+
+    // a quantity of information, stored as nats
+    quantity<hu::nat::info> nnats(2 * si::kilo * hartleys);
+    cout << "nats= " << nnats << endl;
+
+    // how many bytes are in a kibi-byte?
+    cout << conversion_factor(kibi * byte, byte) << " bytes in a kibi-byte" << endl;
+
+    // how many bits are in a mebi-byte?
+    cout << conversion_factor(mebi * byte, bit) << " bits in a mebi-byte" << endl;
+
+    // how many hartleys are in a milli-nat?
+    cout << conversion_factor(si::milli * nat, hartley) << " hartleys in a milli-nat" << endl;
+
+    // compute the entropy of a fair coin flip, in various units of information:
+    cout << "entropy in bits= " << bernoulli_entropy(0.5, bits) << endl;
+    cout << "entropy in nats= " << bernoulli_entropy(0.5, nats) << endl;
+    cout << "entropy in hartleys= " << bernoulli_entropy(0.5, hartleys) << endl;
+    cout << "entropy in shannons= " << bernoulli_entropy(0.5, shannons) << endl;
+    cout << "entropy in bytes= " << bernoulli_entropy(0.5, bytes) << endl;
+
+    return 0;
+}
diff --git a/example/kitchen_sink.cpp b/example/kitchen_sink.cpp
new file mode 100644
index 0000000..ece126b
--- /dev/null
+++ b/example/kitchen_sink.cpp
@@ -0,0 +1,542 @@
+// Boost.Units - A C++ library for zero-overhead dimensional analysis and 
+// unit/quantity manipulation and conversion
+//
+// Copyright (C) 2003-2008 Matthias Christian Schabel
+// Copyright (C) 2008 Steven Watanabe
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+/** 
+\file
+    
+\brief kitchen_sink.cpp
+
+\details
+More extensive quantity tests.
+
+Output:
+@verbatim
+
+//[kitchen_sink_output_1
+S1 :    2
+X1 :    2
+X2 :    (4/3)
+U1 :    N
+U2 :    J
+Q1 :    1 N
+Q2 :    2 J
+//]
+
+//[kitchen_sink_output_2
+U1*S1 : 2 N
+S1*U1 : 2 N
+U1/S1 : 0.5 N
+S1/U1 : 2 m^-1 kg^-1 s^2
+//]
+
+//[kitchen_sink_output_3
+U1+U1 : N
+U1-U1 : N
+U1*U1 : m^2 kg^2 s^-4
+U1/U1 : dimensionless
+U1*U2 : m^3 kg^2 s^-4
+U1/U2 : m^-1
+U1^X  : m^2 kg^2 s^-4
+X1vU1 : m^(1/2) kg^(1/2) s^-1
+U1^X2 : m^(4/3) kg^(4/3) s^(-8/3)
+X2vU1 : m^(3/4) kg^(3/4) s^(-3/2)
+//]
+
+//[kitchen_sink_output_4
+Q1*S1 : 2 N
+S1*Q1 : 2 N
+Q1/S1 : 0.5 N
+S1/Q1 : 2 m^-1 kg^-1 s^2
+//]
+
+//[kitchen_sink_output_5
+U1*Q1 : 1 m^2 kg^2 s^-4
+Q1*U1 : 1 m^2 kg^2 s^-4
+U1/Q1 : 1 dimensionless
+Q1/U1 : 1 dimensionless
+//]
+
+//[kitchen_sink_output_6
++Q1   : 1 N
+-Q1   : -1 N
+Q1+Q1 : 2 N
+Q1-Q1 : 0 N
+Q1*Q1 : 1 m^2 kg^2 s^-4
+Q1/Q1 : 1 dimensionless
+Q1*Q2 : 2 m^3 kg^2 s^-4
+Q1/Q2 : 0.5 m^-1
+Q1^X1 : 1 m^2 kg^2 s^-4
+X1vQ1 : 1 m^(1/2) kg^(1/2) s^-1
+Q1^X2 : 1 m^(4/3) kg^(4/3) s^(-8/3)
+X2vQ1 : 1 m^(3/4) kg^(3/4) s^(-3/2)
+//]
+
+//[kitchen_sink_output_7
+l1 == l2    false
+l1 != l2    true
+l1 <= l2    true
+l1 < l2     true
+l1 >= l2    false
+l1 > l2     false
+//]
+
+dimless = 1
+
+//[kitchen_sink_output_8
+v1 = 2 m s^-1
+//]
+
+//[kitchen_sink_output_9
+F  = 1 N
+dx = 1 m
+E  = 1 J
+//]
+
+//[kitchen_sink_output_10
+r = 5e-07 m
+P = 101325 Pa
+V = 5.23599e-19 m^3
+T = 310 K
+n = 2.05835e-17 mol
+R = 8.314472 m^2 kg s^-2 K^-1 mol^-1 (rel. unc. = 1.8e-06)
+//]
+
+//[kitchen_sink_output_11
+theta            = 0.375 rd
+sin(theta)       = 0.366273 dimensionless
+asin(sin(theta)) = 0.375 rd
+//]
+
+//[kitchen_sink_output_12
+V   = (12.5,0) V
+I   = (3,4) A
+Z   = (1.5,-2) Ohm
+I*Z = (12.5,0) V
+//]
+
+//[kitchen_sink_output_13
+x+y-w         = 0.48(+/-0.632772) m
+w*x           = 9.04(+/-0.904885) m^2
+x/y           = 0.666667(+/-0.149071) dimensionless
+//]
+
+//[kitchen_sink_output_14
+w*y^2/(u*x)^2 = 10.17(+/-3.52328) m^-1
+w/(u*x)^(1/2) = 3.19612(+/-0.160431) dimensionless
+//]
+
+//[kitchen_sink_output_15
+I*w   = m^2 kg s^-1 rad^-1
+I*w/L = dimensionless
+I*w^2 = J
+//]
+
+//[kitchen_sink_output_16
+1 F
+1 kat
+1 S
+1 C
+1 V
+1 J
+1 N
+1 Hz
+1 lx
+1 H
+1 lm
+1 Wb
+1 T
+1 W
+1 Pa
+1 Ohm
+//]
+
+//[kitchen_sink_output_18
+1 farad
+1 katal
+1 siemen
+1 coulomb
+1 volt
+1 joule
+1 newton
+1 hertz
+1 lux
+1 henry
+1 lumen
+1 weber
+1 tesla
+1 watt
+1 pascal
+1 ohm
+//]
+
+@endverbatim
+**/
+
+#include <cmath>
+#include <complex>
+#include <iostream>
+
+#include <boost/typeof/std/complex.hpp>
+
+#include <boost/units/cmath.hpp>
+#include <boost/units/io.hpp>
+#include <boost/units/systems/si.hpp>
+#include <boost/units/systems/si/codata/physico-chemical_constants.hpp>
+#include <boost/units/systems/si/io.hpp>
+
+#include "measurement.hpp"
+
+namespace boost {
+
+namespace units {
+
+//[kitchen_sink_function_snippet_3
+/// the physical definition of work - computed for an arbitrary unit system 
+template<class System,class Y>
+constexpr
+quantity<unit<energy_dimension,System>,Y> 
+work(quantity<unit<force_dimension,System>,Y> F,
+     quantity<unit<length_dimension,System>,Y> dx)
+{
+    return F*dx;
+}
+//]
+
+//[kitchen_sink_function_snippet_4
+/// the ideal gas law in si units
+template<class Y>
+constexpr
+quantity<si::amount,Y> 
+idealGasLaw(const quantity<si::pressure,Y>& P,
+            const quantity<si::volume,Y>& V,
+            const quantity<si::temperature,Y>& T)
+{
+    using namespace boost::units::si;
+    
+    using namespace constants::codata;
+    return (P*V/(R*T));
+}
+//]
+
+} // namespace units
+
+} // namespace boost
+
+int main()
+{    
+    using namespace boost::units;
+    using namespace boost::units::si;
+
+    {
+    //[kitchen_sink_snippet_1
+    /// scalar
+    const double    s1 = 2;
+    
+    const long                  x1 = 2;
+    const static_rational<4,3>  x2;
+    
+    /// define some units
+    force       u1 = newton;
+    energy      u2 = joule;
+    
+    /// define some quantities
+    quantity<force>      q1(1.0*u1);
+    quantity<energy>     q2(2.0*u2);
+    //]
+    
+    /// check scalar, unit, and quantity io
+    std::cout << "S1 :    " << s1 << std::endl
+              << "X1 :    " << x1 << std::endl
+              << "X2 :    " << x2 << std::endl
+              << "U1 :    " << u1 << std::endl
+              << "U2 :    " << u2 << std::endl
+              << "Q1 :    " << q1 << std::endl
+              << "Q2 :    " << q2 << std::endl
+              << std::endl;
+    
+    /// check scalar-unit algebra
+    std::cout //<< "U1+S1 : " << u1+s1 << std::endl    // illegal
+              //<< "S1+U1 : " << s1+u1 << std::endl    // illegal
+              //<< "U1-S1 : " << u1-s1 << std::endl    // illegal
+              //<< "S1-U1 : " << s1-u1 << std::endl    // illegal
+              << "U1*S1 : " << u1*s1 << std::endl
+              << "S1*U1 : " << s1*u1 << std::endl
+              << "U1/S1 : " << u1/s1 << std::endl
+              << "S1/U1 : " << s1/u1 << std::endl
+              << std::endl;
+    
+    /// check unit-unit algebra
+    std::cout << "U1+U1 : " << u1+u1 << std::endl
+              << "U1-U1 : " << u1-u1 << std::endl
+              << "U1*U1 : " << u1*u1 << std::endl
+              << "U1/U1 : " << u1/u1 << std::endl
+              //<< "U1+U2 : " << u1+u2 << std::endl     // illegal
+              //<< "U1-U2 : " << u1-u2 << std::endl     // illegal
+              << "U1*U2 : " << u1*u2 << std::endl
+              << "U1/U2 : " << u1/u2 << std::endl
+              << "U1^X  : " << pow<2>(u1) << std::endl
+              << "X1vU1 : " << root<2>(u1) << std::endl
+              << "U1^X2 : " << pow<static_rational<4,3> >(u1) << std::endl
+              << "X2vU1 : " << root<static_rational<4,3> >(u1) << std::endl
+              << std::endl;
+    
+    /// check scalar-quantity algebra
+    std::cout //<< "Q1+S1 : " << q1+s1 << std::endl    // illegal
+              //<< "S1+Q1 : " << s1+q1 << std::endl    // illegal
+              //<< "Q1-S1 : " << q1-s1 << std::endl    // illegal
+              //<< "S1-Q1 : " << s1-q1 << std::endl    // illegal
+              << "Q1*S1 : " << q1*s1 << std::endl
+              << "S1*Q1 : " << s1*q1 << std::endl
+              << "Q1/S1 : " << q1/s1 << std::endl
+              << "S1/Q1 : " << s1/q1 << std::endl
+              << std::endl;
+    
+    /// check unit-quantity algebra
+    std::cout //<< "U1+Q1 : " << u1+q1 << std::endl    // illegal
+              //<< "Q1+U1 : " << q1+u1 << std::endl    // illegal
+              //<< "U1-Q1 : " << u1-q1 << std::endl    // illegal
+              //<< "Q1-U1 : " << q1-u1 << std::endl    // illegal
+              << "U1*Q1 : " << u1*q1 << std::endl
+              << "Q1*U1 : " << q1*u1 << std::endl
+              << "U1/Q1 : " << u1/q1 << std::endl
+              << "Q1/U1 : " << q1/u1 << std::endl
+              << std::endl;
+    
+    /// check quantity-quantity algebra
+    std::cout << "+Q1   : " << +q1 << std::endl
+              << "-Q1   : " << -q1 << std::endl
+              << "Q1+Q1 : " << q1+q1 << std::endl
+              << "Q1-Q1 : " << q1-q1 << std::endl
+              << "Q1*Q1 : " << q1*q1 << std::endl
+              << "Q1/Q1 : " << q1/q1 << std::endl
+              //<< "Q1+Q2 : " << q1+q2 << std::endl    // illegal
+              //<< "Q1-Q2 : " << q1-q2 << std::endl    // illegal
+              << "Q1*Q2 : " << q1*q2 << std::endl
+              << "Q1/Q2 : " << q1/q2 << std::endl
+              << "Q1^X1 : " << pow<2>(q1) << std::endl
+              << "X1vQ1 : " << root<2>(q1) << std::endl
+              << "Q1^X2 : " << pow<static_rational<4,3> >(q1) << std::endl
+              << "X2vQ1 : " << root<static_rational<4,3> >(q1) << std::endl
+              << std::endl;
+    
+    //[kitchen_sink_snippet_2
+    /// check comparison tests
+    quantity<length>    l1(1.0*meter),
+                        l2(2.0*meters);
+    //]
+                        
+    std::cout << std::boolalpha
+              << "l1 == l2" << "\t" << (l1 == l2) << std::endl
+              << "l1 != l2" << "\t" << (l1 != l2) << std::endl
+              << "l1 <= l2" << "\t" << (l1 <= l2) << std::endl
+              << "l1 < l2 " << "\t" << (l1  < l2) << std::endl
+              << "l1 >= l2" << "\t" << (l1 >= l2) << std::endl
+              << "l1 > l2 " << "\t" << (l1  > l2) << std::endl
+              << std::endl;
+    
+    //[kitchen_sink_snippet_3
+    /// check implicit unit conversion from dimensionless to value_type  
+    const double    dimless = (q1/q1);
+    //]
+    
+    std::cout << "dimless = " << dimless << std::endl
+              << std::endl;
+             
+    quantity<velocity>  v1 = 2.0*meters/second;
+        
+    std::cout << "v1 = " << v1 << std::endl
+              << std::endl;
+    
+    //[kitchen_sink_snippet_4
+    /// test calcuation of work
+    quantity<force>       F(1.0*newton);
+    quantity<length>      dx(1.0*meter);
+    quantity<energy>      E(work(F,dx));
+    //]
+    
+    std::cout << "F  = " << F << std::endl
+              << "dx = " << dx << std::endl
+              << "E  = " << E << std::endl
+              << std::endl;
+    
+    {
+    //[kitchen_sink_snippet_5
+    /// test ideal gas law
+    quantity<temperature>   T = (273.+37.)*kelvin;
+    quantity<pressure>      P = 1.01325e5*pascals;
+    quantity<length>        r = 0.5e-6*meters;
+    quantity<volume>        V = (4.0/3.0)*3.141592*pow<3>(r);
+    quantity<amount>        n(idealGasLaw(P,V,T));
+    //]
+    
+    std::cout << "r = " << r << std::endl
+              << "P = " << P << std::endl
+              << "V = " << V << std::endl
+              << "T = " << T << std::endl
+              << "n = " << n << std::endl
+              #if BOOST_UNITS_HAS_TYPEOF
+              << "R = " << constants::codata::R << std::endl
+              #else
+              << "no typeof" << std::endl
+              #endif // BOOST_UNITS_HAS_TYPEOF
+              << std::endl;
+    }         
+    
+    //[kitchen_sink_snippet_6
+    /// test trig stuff
+    quantity<plane_angle>           theta = 0.375*radians;
+    quantity<dimensionless>         sin_theta = sin(theta);
+    quantity<plane_angle>           thetap = asin(sin_theta);
+    //]
+    
+    std::cout << "theta            = " << theta << std::endl
+              << "sin(theta)       = " << sin_theta << std::endl
+              << "asin(sin(theta)) = " << thetap << std::endl
+              << std::endl;
+    
+    /// test implicit conversion of dimensionless to value
+    double  tmp = sin_theta;
+    
+    tmp = sin_theta;
+    
+    /// test implicit conversion from value to dimensionless
+    quantity<dimensionless>     tmpp = tmp;
+    
+    tmpp = tmp;
+    
+    /// check complex quantities
+    typedef std::complex<double>    complex_type;
+    
+    //[kitchen_sink_snippet_7
+    quantity<electric_potential,complex_type> v = complex_type(12.5,0.0)*volts;
+    quantity<current,complex_type>            i = complex_type(3.0,4.0)*amperes;
+    quantity<resistance,complex_type>         z = complex_type(1.5,-2.0)*ohms;
+    //]
+    
+    std::cout << "V   = " << v << std::endl
+              << "I   = " << i << std::endl
+              << "Z   = " << z << std::endl
+              << "I*Z = " << i*z << std::endl
+              << std::endl;
+    
+    /// check quantities using user-defined type encapsulating error propagation
+
+    //[kitchen_sink_snippet_8
+    quantity<length,measurement<double> >
+        u(measurement<double>(1.0,0.0)*meters),
+        w(measurement<double>(4.52,0.02)*meters),
+        x(measurement<double>(2.0,0.2)*meters),
+        y(measurement<double>(3.0,0.6)*meters);
+    //]
+                                        
+    std::cout << "x+y-w         = " << x+y-w << std::endl
+              << "w*x           = " << w*x << std::endl
+              << "x/y           = " << x/y << std::endl
+              << "w*y^2/(u*x)^2 = " << w*y*y/pow<2>(u*x) << std::endl
+              << "w/(u*x)^(1/2) = " << w/pow< static_rational<1,2> >(u*x)
+              << std::endl << std::endl;
+    }
+    
+    /// check moment of inertia/angular momentum/rotational energy
+    
+    //[kitchen_sink_snippet_9
+    std::cout << symbol_format
+              << "I*w   = " << moment_of_inertia()*angular_velocity() << std::endl
+              << "I*w/L = " << moment_of_inertia()*angular_velocity()/angular_momentum() << std::endl
+              << "I*w^2 = " << moment_of_inertia()*pow<2>(angular_velocity()) << std::endl
+              << std::endl;
+    //]
+    
+    //[kitchen_sink_snippet_10
+//    std::cout << typename_format 
+//              << quantity<capacitance>(1.0*farad) << std::endl
+//              << quantity<catalytic_activity>(1.0*katal) << std::endl
+//              << quantity<conductance>(1.0*siemen) << std::endl
+//              << quantity<electric_charge>(1.0*coulomb) << std::endl
+//              << quantity<electric_potential>(1.0*volt) << std::endl
+//              << quantity<energy>(1.0*joule) << std::endl
+//              << quantity<force>(1.0*newton) << std::endl
+//              << quantity<frequency>(1.0*hertz) << std::endl
+//              << quantity<illuminance>(1.0*lux) << std::endl
+//              << quantity<inductance>(1.0*henry) << std::endl
+//              << quantity<luminous_flux>(1.0*lumen) << std::endl
+//              << quantity<magnetic_flux>(1.0*weber) << std::endl
+//              << quantity<magnetic_flux_density>(1.0*tesla) << std::endl
+//              << quantity<power>(1.0*watt) << std::endl
+//              << quantity<pressure>(1.0*pascals) << std::endl
+//              << quantity<resistance>(1.0*ohm) << std::endl
+//              << std::endl;
+    //]
+    
+    //[kitchen_sink_snippet_11
+//    std::cout << raw_format 
+//              << quantity<capacitance>(1.0*farad) << std::endl
+//              << quantity<catalytic_activity>(1.0*katal) << std::endl
+//              << quantity<conductance>(1.0*siemen) << std::endl
+//              << quantity<electric_charge>(1.0*coulomb) << std::endl
+//              << quantity<electric_potential>(1.0*volt) << std::endl
+//              << quantity<energy>(1.0*joule) << std::endl
+//              << quantity<force>(1.0*newton) << std::endl
+//              << quantity<frequency>(1.0*hertz) << std::endl
+//              << quantity<illuminance>(1.0*lux) << std::endl
+//              << quantity<inductance>(1.0*henry) << std::endl
+//              << quantity<luminous_flux>(1.0*lumen) << std::endl
+//              << quantity<magnetic_flux>(1.0*weber) << std::endl
+//              << quantity<magnetic_flux_density>(1.0*tesla) << std::endl
+//              << quantity<power>(1.0*watt) << std::endl
+//              << quantity<pressure>(1.0*pascals) << std::endl
+//              << quantity<resistance>(1.0*ohm) << std::endl
+//              << std::endl;
+    //]
+    
+    //[kitchen_sink_snippet_12
+    std::cout << symbol_format 
+              << quantity<capacitance>(1.0*farad) << std::endl
+              << quantity<catalytic_activity>(1.0*katal) << std::endl
+              << quantity<conductance>(1.0*siemen) << std::endl
+              << quantity<electric_charge>(1.0*coulomb) << std::endl
+              << quantity<electric_potential>(1.0*volt) << std::endl
+              << quantity<energy>(1.0*joule) << std::endl
+              << quantity<force>(1.0*newton) << std::endl
+              << quantity<frequency>(1.0*hertz) << std::endl
+              << quantity<illuminance>(1.0*lux) << std::endl
+              << quantity<inductance>(1.0*henry) << std::endl
+              << quantity<luminous_flux>(1.0*lumen) << std::endl
+              << quantity<magnetic_flux>(1.0*weber) << std::endl
+              << quantity<magnetic_flux_density>(1.0*tesla) << std::endl
+              << quantity<power>(1.0*watt) << std::endl
+              << quantity<pressure>(1.0*pascals) << std::endl
+              << quantity<resistance>(1.0*ohm) << std::endl
+              << std::endl;
+    //]
+    
+    //[kitchen_sink_snippet_13
+    std::cout << name_format 
+              << quantity<capacitance>(1.0*farad) << std::endl
+              << quantity<catalytic_activity>(1.0*katal) << std::endl
+              << quantity<conductance>(1.0*siemen) << std::endl
+              << quantity<electric_charge>(1.0*coulomb) << std::endl
+              << quantity<electric_potential>(1.0*volt) << std::endl
+              << quantity<energy>(1.0*joule) << std::endl
+              << quantity<force>(1.0*newton) << std::endl
+              << quantity<frequency>(1.0*hertz) << std::endl
+              << quantity<illuminance>(1.0*lux) << std::endl
+              << quantity<inductance>(1.0*henry) << std::endl
+              << quantity<luminous_flux>(1.0*lumen) << std::endl
+              << quantity<magnetic_flux>(1.0*weber) << std::endl
+              << quantity<magnetic_flux_density>(1.0*tesla) << std::endl
+              << quantity<power>(1.0*watt) << std::endl
+              << quantity<pressure>(1.0*pascals) << std::endl
+              << quantity<resistance>(1.0*ohm) << std::endl
+              << std::endl;
+    //]
+
+    return 0;
+}
diff --git a/example/lambda.cpp b/example/lambda.cpp
new file mode 100644
index 0000000..0fbac91
--- /dev/null
+++ b/example/lambda.cpp
@@ -0,0 +1,157 @@
+// Boost.Units - A C++ library for zero-overhead dimensional analysis and
+// unit/quantity manipulation and conversion
+//
+// Copyright (C) 2003-2008 Matthias Christian Schabel
+// Copyright (C) 2008 Steven Watanabe
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// $Id: lambda.cpp 27 2008-06-16 14:50:58Z maehne $
+
+////////////////////////////////////////////////////////////////////////
+///
+/// \file lambda.cpp
+///
+/// \brief Example demonstrating the usage of Boost.Units' quantity,
+///        unit, and absolute types in functors created with the
+///        Boost.Lambda library and stored in Boost.Function objects.
+///
+/// \author Torsten Maehne
+/// \date   2008-06-04
+///
+/// A mechanical, electrical, geometrical, and thermal example
+/// demonstrate how to use Boost.Units' quantity, unit, and absolute
+/// types in lambda expressions. The resulting functors can be stored
+/// in boost::function objects. It is also shown how to work around a
+/// limitation of Boost.Lambda's bind() to help it to find the correct
+/// overloaded function by specifying its signature with a
+/// static_cast.
+///
+////////////////////////////////////////////////////////////////////////
+
+#include <iostream>
+#include <boost/function.hpp>
+#include <boost/units/io.hpp>
+#include <boost/units/cmath.hpp>
+#include <boost/units/pow.hpp>
+#include <boost/units/systems/si.hpp>
+#include <boost/units/absolute.hpp>
+
+// Include boost/units/lambda.hpp instead of boost/lambda/lambda.hpp
+// for a convenient usage of Boost.Units' quantity, unit, and absolute
+// types in lambda expressions. The header augments Boost.Lambda's
+// return type detuction system to recognize the new types so that not
+// for each arithmetic operation the return type needs to be
+// explicitely specified.
+#include <boost/units/lambda.hpp>
+
+#include <boost/lambda/bind.hpp>
+
+static const double pi = 3.14159265358979323846;
+
+//[lambda_snippet_1
+
+int main(int argc, char **argv) {
+
+   using namespace std;
+   namespace bl = boost::lambda;
+   namespace bu = boost::units;
+   namespace si = boost::units::si;
+
+
+   ////////////////////////////////////////////////////////////////////////
+   // Mechanical example: linear accelerated movement
+   ////////////////////////////////////////////////////////////////////////
+
+   // Initial condition variables for acceleration, speed, and displacement
+   bu::quantity<si::acceleration> a = 2.0 * si::meters_per_second_squared;
+   bu::quantity<si::velocity> v = 1.0 * si::meters_per_second;
+   bu::quantity<si::length> s0 = 0.5 * si::meter;
+
+   // Displacement over time
+   boost::function<bu::quantity<si::length> (bu::quantity<si::time>) >
+       s = 0.5 * bl::var(a) * bl::_1 * bl::_1
+           + bl::var(v) * bl::_1
+           + bl::var(s0);
+
+   cout << "Linear accelerated movement:" << endl
+        << "a = " << a << ", v = " << v << ", s0 = " << s0 << endl
+        << "s(1.0 * si::second) = " << s(1.0 * si::second) << endl
+        << endl;
+
+   // Change initial conditions
+   a = 1.0 * si::meters_per_second_squared;
+   v = 2.0 * si::meters_per_second;
+   s0 = -1.5 * si::meter;
+
+   cout << "a = " << a << ", v = " << v << ", s0 = " << s0 << endl
+        << "s(1.0 * si::second) = " << s(1.0 * si::second) << endl
+        << endl;
+
+
+   ////////////////////////////////////////////////////////////////////////
+   // Electrical example: oscillating current
+   ////////////////////////////////////////////////////////////////////////
+
+   // Constants for the current amplitude, frequency, and offset current
+   const bu::quantity<si::current> iamp = 1.5 * si::ampere;
+   const bu::quantity<si::frequency> f = 1.0e3 * si::hertz;
+   const bu::quantity<si::current> i0 = 0.5 * si::ampere;
+
+   // The invocation of the sin function needs to be postponed using
+   // bind to specify the oscillation function. A lengthy static_cast
+   // to the function pointer referencing boost::units::sin() is needed
+   // to avoid an "unresolved overloaded function type" error.
+   boost::function<bu::quantity<si::current> (bu::quantity<si::time>) >
+       i = iamp
+           * bl::bind(static_cast<bu::dimensionless_quantity<si::system, double>::type (*)(const bu::quantity<si::plane_angle>&)>(bu::sin),
+                      2.0 * pi * si::radian * f * bl::_1)
+           + i0;
+
+   cout << "Oscillating current:" << endl
+        << "iamp = " << iamp << ", f = " << f << ", i0 = " << i0 << endl
+        << "i(1.25e-3 * si::second) = " << i(1.25e-3 * si::second) << endl
+        << endl;
+
+
+   ////////////////////////////////////////////////////////////////////////
+   // Geometric example: area calculation for a square
+   ////////////////////////////////////////////////////////////////////////
+
+   // Length constant
+   const bu::quantity<si::length> l = 1.5 * si::meter;
+
+   // Again an ugly static_cast is needed to bind pow<2> to the first
+   // function argument.
+   boost::function<bu::quantity<si::area> (bu::quantity<si::length>) >
+       A = bl::bind(static_cast<bu::quantity<si::area> (*)(const bu::quantity<si::length>&)>(bu::pow<2>),
+                    bl::_1);
+
+   cout << "Area of a square:" << endl
+        << "A(" << l <<") = " << A(l) << endl << endl;
+
+
+   ////////////////////////////////////////////////////////////////////////
+   // Thermal example: temperature difference of two absolute temperatures
+   ////////////////////////////////////////////////////////////////////////
+
+   // Absolute temperature constants
+   const bu::quantity<bu::absolute<si::temperature> >
+       Tref = 273.15 * bu::absolute<si::temperature>();
+   const bu::quantity<bu::absolute<si::temperature> >
+       Tamb = 300.00 * bu::absolute<si::temperature>();
+
+   boost::function<bu::quantity<si::temperature> (bu::quantity<bu::absolute<si::temperature> >,
+                                                  bu::quantity<bu::absolute<si::temperature> >)>
+       dT = bl::_2 - bl::_1;
+
+   cout << "Temperature difference of two absolute temperatures:" << endl
+        << "dT(" << Tref << ", " << Tamb << ") = " << dT(Tref, Tamb) << endl
+        << endl;
+
+
+   return 0;
+}
+//]
diff --git a/example/measurement.hpp b/example/measurement.hpp
new file mode 100644
index 0000000..7206302
--- /dev/null
+++ b/example/measurement.hpp
@@ -0,0 +1,344 @@
+// Boost.Units - A C++ library for zero-overhead dimensional analysis and 
+// unit/quantity manipulation and conversion
+//
+// Copyright (C) 2003-2008 Matthias Christian Schabel
+// Copyright (C) 2008 Steven Watanabe
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_UNITS_MEASUREMENT_HPP
+#define BOOST_UNITS_MEASUREMENT_HPP
+
+#include <cmath>
+#include <cstdlib>
+#include <iomanip>
+#include <iostream>
+
+#include <boost/io/ios_state.hpp>
+#include <boost/units/static_rational.hpp>
+
+namespace boost {
+
+namespace units {
+
+namespace sqr_namespace /**/ {
+
+template<class Y>
+constexpr
+Y sqr(Y val)
+{ return val*val; }
+
+} // namespace
+
+using sqr_namespace::sqr;
+
+template<class Y>
+class measurement
+{    
+    public:
+        typedef measurement<Y>                  this_type;
+        typedef Y                               value_type;
+        
+        constexpr measurement(const value_type& val = value_type(),
+                    const value_type& err = value_type()) : 
+            value_(val),
+            uncertainty_(std::abs(err)) 
+        { }
+        
+        constexpr measurement(const this_type& source) : 
+            value_(source.value_),
+            uncertainty_(source.uncertainty_) 
+        { }
+        
+        //~measurement() { }
+        
+        constexpr this_type& operator=(const this_type& source)
+        {
+            if (this == &source) return *this;
+            
+            value_ = source.value_;
+            uncertainty_ = source.uncertainty_;
+            
+            return *this;
+        }
+        
+        constexpr operator value_type() const    { return value_; }
+        
+        constexpr value_type value() const       { return value_; }
+        constexpr value_type uncertainty() const { return uncertainty_; }
+        constexpr value_type lower_bound() const { return value_-uncertainty_; }
+        constexpr value_type upper_bound() const { return value_+uncertainty_; }
+        
+        constexpr this_type& operator+=(const value_type& val)            
+        { 
+            value_ += val; 
+            return *this; 
+        }
+        
+        constexpr this_type& operator-=(const value_type& val)            
+        { 
+            value_ -= val; 
+            return *this; 
+        }
+        
+        constexpr this_type& operator*=(const value_type& val)            
+        { 
+            value_ *= val; 
+            uncertainty_ *= val; 
+            return *this; 
+        }
+        
+        constexpr this_type& operator/=(const value_type& val)            
+        { 
+            value_ /= val; 
+            uncertainty_ /= val; 
+            return *this; 
+        }
+        
+        constexpr this_type& operator+=(const this_type& /*source*/);
+        constexpr this_type& operator-=(const this_type& /*source*/);        
+        constexpr this_type& operator*=(const this_type& /*source*/);        
+        constexpr this_type& operator/=(const this_type& /*source*/);
+
+    private:
+        value_type          value_,
+                            uncertainty_;
+};
+
+}
+
+}
+
+#if BOOST_UNITS_HAS_BOOST_TYPEOF
+
+BOOST_TYPEOF_REGISTER_TEMPLATE(boost::units::measurement, 1)
+
+#endif
+
+namespace boost {
+
+namespace units {
+
+template<class Y>
+inline
+constexpr
+measurement<Y>&
+measurement<Y>::operator+=(const this_type& source)
+{
+    uncertainty_ = std::sqrt(sqr(uncertainty_)+sqr(source.uncertainty_));
+    value_ += source.value_;
+    
+    return *this;
+}
+
+template<class Y>
+inline
+constexpr
+measurement<Y>&
+measurement<Y>::operator-=(const this_type& source)
+{
+    uncertainty_ = std::sqrt(sqr(uncertainty_)+sqr(source.uncertainty_));
+    value_ -= source.value_;
+    
+    return *this;
+}
+
+template<class Y>
+inline
+constexpr
+measurement<Y>&
+measurement<Y>::operator*=(const this_type& source)
+{
+    uncertainty_ = (value_*source.value_)*
+              std::sqrt(sqr(uncertainty_/value_)+
+                        sqr(source.uncertainty_/source.value_));
+    value_ *= source.value_;
+    
+    return *this;
+}
+
+template<class Y>
+inline
+constexpr
+measurement<Y>&
+measurement<Y>::operator/=(const this_type& source)
+{
+    uncertainty_ = (value_/source.value_)*
+              std::sqrt(sqr(uncertainty_/value_)+
+                        sqr(source.uncertainty_/source.value_));
+    value_ /= source.value_;
+    
+    return *this;
+}
+
+// value_type op measurement
+template<class Y>
+inline
+constexpr
+measurement<Y>
+operator+(Y lhs,const measurement<Y>& rhs)
+{
+    return (measurement<Y>(lhs,Y(0))+=rhs);
+}
+
+template<class Y>
+inline
+constexpr
+measurement<Y>
+operator-(Y lhs,const measurement<Y>& rhs)
+{
+    return (measurement<Y>(lhs,Y(0))-=rhs);
+}
+
+template<class Y>
+inline
+constexpr
+measurement<Y>
+operator*(Y lhs,const measurement<Y>& rhs)
+{
+    return (measurement<Y>(lhs,Y(0))*=rhs);
+}
+
+template<class Y>
+inline
+constexpr
+measurement<Y>
+operator/(Y lhs,const measurement<Y>& rhs)
+{
+    return (measurement<Y>(lhs,Y(0))/=rhs);
+}
+
+// measurement op value_type
+template<class Y>
+inline
+constexpr
+measurement<Y>
+operator+(const measurement<Y>& lhs,Y rhs)
+{
+    return (measurement<Y>(lhs)+=measurement<Y>(rhs,Y(0)));
+}
+
+template<class Y>
+inline
+constexpr
+measurement<Y>
+operator-(const measurement<Y>& lhs,Y rhs)
+{
+    return (measurement<Y>(lhs)-=measurement<Y>(rhs,Y(0)));
+}
+
+template<class Y>
+inline
+constexpr
+measurement<Y>
+operator*(const measurement<Y>& lhs,Y rhs)
+{
+    return (measurement<Y>(lhs)*=measurement<Y>(rhs,Y(0)));
+}
+
+template<class Y>
+inline
+constexpr
+measurement<Y>
+operator/(const measurement<Y>& lhs,Y rhs)
+{
+    return (measurement<Y>(lhs)/=measurement<Y>(rhs,Y(0)));
+}
+
+// measurement op measurement
+template<class Y>
+inline
+constexpr
+measurement<Y>
+operator+(const measurement<Y>& lhs,const measurement<Y>& rhs)
+{
+    return (measurement<Y>(lhs)+=rhs);
+}
+
+template<class Y>
+inline
+constexpr
+measurement<Y>
+operator-(const measurement<Y>& lhs,const measurement<Y>& rhs)
+{
+    return (measurement<Y>(lhs)-=rhs);
+}
+
+template<class Y>
+inline
+constexpr
+measurement<Y>
+operator*(const measurement<Y>& lhs,const measurement<Y>& rhs)
+{
+    return (measurement<Y>(lhs)*=rhs);
+}
+
+template<class Y>
+inline
+constexpr
+measurement<Y>
+operator/(const measurement<Y>& lhs,const measurement<Y>& rhs)
+{
+    return (measurement<Y>(lhs)/=rhs);
+}
+
+/// specialize power typeof helper
+template<class Y,long N,long D> 
+struct power_typeof_helper<measurement<Y>,static_rational<N,D> >
+{ 
+    typedef measurement<
+        typename power_typeof_helper<Y,static_rational<N,D> >::type
+    > type; 
+    
+    static constexpr type value(const measurement<Y>& x)  
+    { 
+        const static_rational<N,D>  rat;
+
+        const Y m = Y(rat.numerator())/Y(rat.denominator()),
+                newval = std::pow(x.value(),m),
+                err = newval*std::sqrt(std::pow(m*x.uncertainty()/x.value(),2));
+        
+        return type(newval,err);
+    }
+};
+
+/// specialize root typeof helper
+template<class Y,long N,long D> 
+struct root_typeof_helper<measurement<Y>,static_rational<N,D> >                
+{ 
+    typedef measurement<
+        typename root_typeof_helper<Y,static_rational<N,D> >::type
+    > type; 
+    
+    static constexpr type value(const measurement<Y>& x)  
+    { 
+        const static_rational<N,D>  rat;
+
+        const Y m = Y(rat.denominator())/Y(rat.numerator()),
+                newval = std::pow(x.value(),m),
+                err = newval*std::sqrt(std::pow(m*x.uncertainty()/x.value(),2));
+        
+        return type(newval,err);
+    }
+};
+
+// stream output
+template<class Y>
+inline
+std::ostream& operator<<(std::ostream& os,const measurement<Y>& val)
+{
+    boost::io::ios_precision_saver precision_saver(os);
+    boost::io::ios_flags_saver flags_saver(os);
+    
+    os << val.value() << "(+/-" << val.uncertainty() << ")";
+    
+    return os;
+}
+
+} // namespace units
+
+} // namespace boost
+
+#endif // BOOST_UNITS_MEASUREMENT_HPP
diff --git a/example/non_base_dimension.cpp b/example/non_base_dimension.cpp
new file mode 100644
index 0000000..4476a34
--- /dev/null
+++ b/example/non_base_dimension.cpp
@@ -0,0 +1,78 @@
+// Boost.Units - A C++ library for zero-overhead dimensional analysis and 
+// unit/quantity manipulation and conversion
+//
+// Copyright (C) 2003-2008 Matthias Christian Schabel
+// Copyright (C) 2007-2008 Steven Watanabe
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+/** 
+\file
+    
+\brief non_base_dimension.cpp
+
+\details
+Another example of user-defined units with conversions.
+
+Output:
+@verbatim
+
+//[non_base_dimension_output
+//]
+
+@endverbatim
+**/
+
+#include <iostream>
+
+#include <boost/units/io.hpp>
+#include <boost/units/conversion.hpp>
+#include <boost/units/unit.hpp>
+#include <boost/units/quantity.hpp>
+#include <boost/units/physical_dimensions.hpp>
+#include <boost/units/base_unit.hpp>
+#include <boost/units/make_system.hpp>
+
+namespace boost {
+
+namespace units {
+
+//[non_base_dimension_snippet_1
+
+struct imperial_gallon_tag :
+    base_unit<imperial_gallon_tag, volume_dimension, 1> { };
+
+typedef make_system<imperial_gallon_tag>::type imperial;
+
+typedef unit<volume_dimension,imperial> imperial_gallon;
+
+struct us_gallon_tag : base_unit<us_gallon_tag, volume_dimension, 2> { };
+
+typedef make_system<us_gallon_tag>::type us;
+
+typedef unit<volume_dimension,us> us_gallon;
+
+//]
+
+} // namespace units
+
+} // namespace boost
+
+BOOST_UNITS_DEFINE_CONVERSION_FACTOR(boost::units::imperial_gallon_tag,
+                                     boost::units::us_gallon_tag,
+                                     double, 1.2009499255);
+
+using namespace boost::units;
+
+int main(void)
+{
+    quantity<imperial_gallon>   ig1(1.0*imperial_gallon());
+    quantity<us_gallon>         ug1(1.0*us_gallon());
+    
+    quantity<imperial_gallon>   ig2(ug1);
+    quantity<us_gallon>         ug2(ig1);
+    
+    return 0;
+}
diff --git a/example/performance.cpp b/example/performance.cpp
new file mode 100644
index 0000000..fd2abe1
--- /dev/null
+++ b/example/performance.cpp
@@ -0,0 +1,395 @@
+// Boost.Units - A C++ library for zero-overhead dimensional analysis and 
+// unit/quantity manipulation and conversion
+//
+// Copyright (C) 2003-2008 Matthias Christian Schabel
+// Copyright (C) 2008 Steven Watanabe
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+/** 
+\file
+    
+\brief performance.cpp
+
+\details
+Test runtime performance.
+
+Output:
+@verbatim
+
+multiplying ublas::matrix<double>(1000, 1000) : 25.03 seconds
+multiplying ublas::matrix<quantity>(1000, 1000) : 24.49 seconds
+tiled_matrix_multiply<double>(1000, 1000) : 1.12 seconds
+tiled_matrix_multiply<quantity>(1000, 1000) : 1.16 seconds
+solving y' = 1 - x + 4 * y with double: 1.97 seconds
+solving y' = 1 - x + 4 * y with quantity: 1.84 seconds
+
+@endverbatim
+**/
+
+#define _SCL_SECURE_NO_WARNINGS
+
+#include <cstdlib>
+#include <ctime>
+#include <algorithm>
+#include <iostream>
+#include <iomanip>
+
+#include <boost/config.hpp>
+#include <boost/timer.hpp>
+#include <boost/utility/result_of.hpp>
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4267; disable:4127; disable:4244; disable:4100)
+#endif
+
+#include <boost/numeric/ublas/matrix.hpp>
+
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#include <boost/units/quantity.hpp>
+#include <boost/units/systems/si.hpp>
+#include <boost/units/cmath.hpp>
+#include <boost/units/io.hpp>
+
+enum {
+    tile_block_size = 24
+};
+
+template<class T0, class T1, class Out>
+void tiled_multiply_carray_inner(T0* first,
+                                 T1* second,
+                                 Out* out,
+                                 int totalwidth,
+                                 int width2,
+                                 int height1,
+                                 int common) {
+    for(int j = 0; j < height1; ++j) {
+        for(int i = 0; i < width2; ++i) {
+            Out value = out[j * totalwidth + i];
+            for(int k = 0; k < common; ++k) {
+                value += first[k + totalwidth * j] * second[k * totalwidth + i];
+            }
+            out[j * totalwidth + i] = value;
+        }
+    }
+}
+
+template<class T0, class T1, class Out>
+void tiled_multiply_carray_outer(T0* first,
+                                 T1* second,
+                                 Out* out,
+                                 int width2,
+                                 int height1,
+                                 int common) {
+    std::fill_n(out, width2 * height1, Out());
+    int j = 0;
+    for(; j < height1 - tile_block_size; j += tile_block_size) {
+        int i = 0;
+        for(; i < width2 - tile_block_size; i += tile_block_size) {
+            int k = 0;
+            for(; k < common - tile_block_size; k += tile_block_size) {
+                tiled_multiply_carray_inner(
+                    &first[k + width2 * j],
+                    &second[k * width2 + i],
+                    &out[j * width2 + i],
+                    width2,
+                    tile_block_size,
+                    tile_block_size,
+                    tile_block_size);
+            }
+            tiled_multiply_carray_inner(
+                &first[k + width2 * j],
+                &second[k * width2 + i],
+                &out[j * width2 + i],
+                width2,
+                tile_block_size,
+                tile_block_size,
+                common - k);
+        }
+        int k = 0;
+        for(; k < common - tile_block_size; k += tile_block_size) {
+            tiled_multiply_carray_inner(
+                &first[k + width2 * j],
+                &second[k * width2 + i],
+                &out[j * width2 + i],
+                width2, width2 - i,
+                tile_block_size,
+                tile_block_size);
+        }
+        tiled_multiply_carray_inner(
+            &first[k + width2 * j],
+            &second[k * width2 + i],
+            &out[j * width2 + i],
+            width2, width2 - i,
+            tile_block_size,
+            common - k);
+    }
+    int i = 0;
+    for(; i < width2 - tile_block_size; i += tile_block_size) {
+        int k = 0;
+        for(; k < common - tile_block_size; k += tile_block_size) {
+            tiled_multiply_carray_inner(
+                &first[k + width2 * j],
+                &second[k * width2 + i],
+                &out[j * width2 + i],
+                width2,
+                tile_block_size,
+                height1 - j,
+                tile_block_size);
+        }
+        tiled_multiply_carray_inner(
+            &first[k + width2 * j],
+            &second[k * width2 + i],
+            &out[j * width2 + i],
+            width2,
+            tile_block_size,
+            height1 - j,
+            common - k);
+    }
+    int k = 0;
+    for(; k < common - tile_block_size; k += tile_block_size) {
+        tiled_multiply_carray_inner(
+            &first[k + width2 * j],
+            &second[k * width2 + i],
+            &out[j * width2 + i],
+            width2,
+            width2 - i,
+            height1 - j,
+            tile_block_size);
+    }
+    tiled_multiply_carray_inner(
+        &first[k + width2 * j],
+        &second[k * width2 + i],
+        &out[j * width2 + i],
+        width2,
+        width2 - i,
+        height1 - j,
+        common - k);
+}
+
+enum { max_value = 1000};
+
+template<class F, class T, class N, class R>
+BOOST_CXX14_CONSTEXPR
+R solve_differential_equation(F f, T lower, T upper, N steps, R start) {
+    typedef typename F::template result<T, R>::type f_result;
+    T h = (upper - lower) / (1.0*steps);
+    for(N i = N(); i < steps; ++i) {
+        R y = start;
+        T x = lower + h * (1.0*i);
+        f_result k1 = f(x, y);
+        f_result k2 = f(x + h / 2.0, y + h * k1 / 2.0);
+        f_result k3 = f(x + h / 2.0, y + h * k2 / 2.0);
+        f_result k4 = f(x + h, y + h * k3);
+        start = y + h * (k1 + 2.0 * k2 + 2.0 * k3 + k4) / 6.0;
+    }
+    return(start);
+}
+
+using namespace boost::units;
+
+//y' = 1 - x + 4 * y
+struct f {
+    template<class Arg1, class Arg2> struct result;
+    
+    BOOST_CONSTEXPR double operator()(const double& x, const double& y) const {
+        return(1.0 - x + 4.0 * y);
+    }
+
+    boost::units::quantity<boost::units::si::velocity>
+    BOOST_CONSTEXPR operator()(const quantity<si::time>& x,
+                               const quantity<si::length>& y) const {
+        using namespace boost::units;
+        using namespace si;
+        return(1.0 * meters / second -
+                x * meters / pow<2>(seconds) +
+                4.0 * y / seconds );
+    }
+};
+
+template<> 
+struct f::result<double,double> {
+    typedef double type;
+};
+
+template<>
+struct f::result<quantity<si::time>, quantity<si::length> > {
+    typedef quantity<si::velocity> type;
+};
+
+
+
+//y' = 1 - x + 4 * y
+//y' - 4 * y = 1 - x
+//e^(-4 * x) * (dy - 4 * y * dx) = e^(-4 * x) * (1 - x) * dx
+//d/dx(y * e ^ (-4 * x)) = e ^ (-4 * x) (1 - x) * dx
+
+//d/dx(y * e ^ (-4 * x)) = e ^ (-4 * x) * dx - x * e ^ (-4 * x) * dx
+//d/dx(y * e ^ (-4 * x)) = d/dx((-3/16 + 1/4 * x) * e ^ (-4 * x))
+//y * e ^ (-4 * x) = (-3/16 + 1/4 * x) * e ^ (-4 * x) + C
+//y = (-3/16 + 1/4 * x) + C/e ^ (-4 * x)
+//y = 1/4 * x - 3/16 + C * e ^ (4 * x)
+
+//y(0) = 1
+//1 = - 3/16 + C
+//C = 19/16
+//y(x) = 1/4 * x - 3/16 + 19/16 * e ^ (4 * x)
+
+
+
+int main() {
+    boost::numeric::ublas::matrix<double> ublas_result;
+    {
+        boost::numeric::ublas::matrix<double> m1(max_value, max_value);
+        boost::numeric::ublas::matrix<double> m2(max_value, max_value);
+        std::srand(1492);
+        for(int i = 0; i < max_value; ++i) {
+            for(int j = 0; j < max_value; ++j) {
+                m1(i,j) = std::rand();
+                m2(i,j) = std::rand();
+            }
+        }
+        std::cout << "multiplying ublas::matrix<double>("
+                  << max_value << ", " << max_value << ") : ";
+        boost::timer timer;
+        ublas_result = (prod(m1, m2));
+        std::cout << timer.elapsed() << " seconds" << std::endl;
+    }
+    typedef boost::numeric::ublas::matrix<
+        boost::units::quantity<boost::units::si::dimensionless>
+    > matrix_type;
+    matrix_type ublas_resultq;
+    {
+        matrix_type m1(max_value, max_value);
+        matrix_type m2(max_value, max_value);
+        std::srand(1492);
+        for(int i = 0; i < max_value; ++i) {
+            for(int j = 0; j < max_value; ++j) {
+                m1(i,j) = std::rand();
+                m2(i,j) = std::rand();
+            }
+        }
+        std::cout << "multiplying ublas::matrix<quantity>("
+                  << max_value << ", " << max_value << ") : ";
+        boost::timer timer;
+        ublas_resultq = (prod(m1, m2));
+        std::cout << timer.elapsed() << " seconds" << std::endl;
+    }
+    std::vector<double> cresult(max_value * max_value);
+    {
+        std::vector<double> m1(max_value * max_value);
+        std::vector<double> m2(max_value * max_value);
+        std::srand(1492);
+        for(int i = 0; i < max_value * max_value; ++i) {
+            m1[i] = std::rand();
+            m2[i] = std::rand();
+        }
+        std::cout << "tiled_matrix_multiply<double>("
+                  << max_value << ", " << max_value << ") : ";
+        boost::timer timer;
+        tiled_multiply_carray_outer(
+            &m1[0],
+            &m2[0],
+            &cresult[0],
+            max_value,
+            max_value,
+            max_value);
+        std::cout << timer.elapsed() << " seconds" << std::endl;
+    }
+    std::vector<
+        boost::units::quantity<boost::units::si::energy>
+    >  cresultq(max_value * max_value);
+    {
+        std::vector<
+            boost::units::quantity<boost::units::si::force>
+        > m1(max_value * max_value);
+        std::vector<
+            boost::units::quantity<boost::units::si::length>
+        > m2(max_value * max_value);
+        std::srand(1492);
+        for(int i = 0; i < max_value * max_value; ++i) {
+            m1[i] = std::rand() * boost::units::si::newtons;
+            m2[i] = std::rand() * boost::units::si::meters;
+        }
+        std::cout << "tiled_matrix_multiply<quantity>("
+                  << max_value << ", " << max_value << ") : ";
+        boost::timer timer;
+        tiled_multiply_carray_outer(
+            &m1[0],
+            &m2[0],
+            &cresultq[0],
+            max_value,
+            max_value,
+            max_value);
+        std::cout << timer.elapsed() << " seconds" << std::endl;
+    }
+    for(int i = 0; i < max_value; ++i) {
+        for(int j = 0; j < max_value; ++j) {
+            const double diff =
+                std::abs(ublas_result(i,j) - cresult[i * max_value + j]);
+            if(diff > ublas_result(i,j) /1e14) {
+                std::cout << std::setprecision(15) << "Uh Oh. ublas_result("
+                          << i << "," << j << ") = " << ublas_result(i,j)
+                          << std::endl
+                          << "cresult[" << i << " * " << max_value << " + "
+                          << j << "] = " << cresult[i * max_value + j]
+                          << std::endl;
+                return(EXIT_FAILURE);
+            }
+        }
+    }
+    {
+        std::vector<double> values(1000);
+        std::cout << "solving y' = 1 - x + 4 * y with double: ";
+        boost::timer timer;
+        for(int i = 0; i < 1000; ++i) {
+            const double x = .1 * i;
+            values[i] = solve_differential_equation(f(), 0.0, x, i * 100, 1.0);
+        }
+        std::cout << timer.elapsed() << " seconds" << std::endl;
+        for(int i = 0; i < 1000; ++i) {
+            const double x = .1 * i;
+            const double value = 1.0/4.0 * x - 3.0/16.0 + 19.0/16.0 * std::exp(4 * x);
+            if(std::abs(values[i] - value) > value / 1e9) {
+                std::cout << std::setprecision(15) << "i = : " << i
+                          << ", value = " << value << " approx = "  << values[i]
+                          << std::endl;
+                return(EXIT_FAILURE);
+            }
+        }
+    }
+    {
+        using namespace boost::units;
+        using namespace si;
+        std::vector<quantity<length> > values(1000);
+        std::cout << "solving y' = 1 - x + 4 * y with quantity: ";
+        boost::timer timer;
+        for(int i = 0; i < 1000; ++i) {
+            const quantity<si::time> x = .1 * i * seconds;
+            values[i] = solve_differential_equation(
+                f(),
+                0.0 * seconds,
+                x,
+                i * 100,
+                1.0 * meters);
+        }
+        std::cout << timer.elapsed() << " seconds" << std::endl;
+        for(int i = 0; i < 1000; ++i) {
+            const double x = .1 * i;
+            const quantity<si::length> value =
+                (1.0/4.0 * x - 3.0/16.0 + 19.0/16.0 * std::exp(4 * x)) * meters;
+            if(abs(values[i] - value) > value / 1e9) {
+                std::cout << std::setprecision(15) << "i = : " << i
+                          << ", value = " << value << " approx = "
+                          << values[i] << std::endl;
+                return(EXIT_FAILURE);
+            }
+        }
+    }
+}
diff --git a/example/quantity.cpp b/example/quantity.cpp
new file mode 100644
index 0000000..e3d3f18
--- /dev/null
+++ b/example/quantity.cpp
@@ -0,0 +1,128 @@
+// Boost.Units - A C++ library for zero-overhead dimensional analysis and 
+// unit/quantity manipulation and conversion
+//
+// Copyright (C) 2003-2008 Matthias Christian Schabel
+// Copyright (C) 2008 Steven Watanabe
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+/** 
+\file
+    
+\brief quantity.cpp
+
+\details
+Test quantity algebra.
+
+Output:
+@verbatim
+
+//[quantity_output_double
+L                                 = 2 m
+L+L                               = 4 m
+L-L                               = 0 m
+L*L                               = 4 m^2
+L/L                               = 1 dimensionless 
+L*meter                           = 2 m^2
+kilograms*(L/seconds)*(L/seconds) = 4 m^2 kg s^-2
+kilograms*(L/seconds)^2           = 4 m^2 kg s^-2
+L^3                               = 8 m^3
+L^(3/2)                           = 2.82843 m^(3/2)
+2vL                               = 1.41421 m^(1/2)
+(3/2)vL                           = 1.5874 m^(2/3)
+//]
+
+//[quantity_output_complex
+L                                 = (3,4) m
+L+L                               = (6,8) m
+L-L                               = (0,0) m
+L*L                               = (-7,24) m^2
+L/L                               = (1,0) dimensionless 
+L*meter                           = (3,4) m^2
+kilograms*(L/seconds)*(L/seconds) = (-7,24) m^2 kg s^-2
+kilograms*(L/seconds)^2           = (-7,24) m^2 kg s^-2
+L^3                               = (-117,44) m^3
+L^(3/2)                           = (2,11) m^(3/2)
+2vL                               = (2,1) m^(1/2)
+(3/2)vL                           = (2.38285,1.69466) m^(2/3)
+//]
+
+@endverbatim
+**/
+
+#include <complex>
+#include <iostream>
+
+#include <boost/mpl/list.hpp>
+
+#include <boost/typeof/std/complex.hpp>
+
+#include <boost/units/pow.hpp>
+#include <boost/units/quantity.hpp>
+#include <boost/units/io.hpp>
+
+#include "test_system.hpp"
+
+int main(void)
+{
+    using namespace boost::units;
+    using namespace boost::units::test;
+
+    {
+    //[quantity_snippet_1
+    quantity<length> L = 2.0*meters;                     // quantity of length
+    quantity<energy> E = kilograms*pow<2>(L/seconds);    // quantity of energy
+    //]
+    
+    std::cout << "L                                 = " << L << std::endl
+              << "L+L                               = " << L+L << std::endl
+              << "L-L                               = " << L-L << std::endl
+              << "L*L                               = " << L*L << std::endl
+              << "L/L                               = " << L/L << std::endl
+              << "L*meter                           = " << L*meter << std::endl
+              << "kilograms*(L/seconds)*(L/seconds) = "
+              << kilograms*(L/seconds)*(L/seconds) << std::endl
+              << "kilograms*(L/seconds)^2           = "
+              << kilograms*pow<2>(L/seconds) << std::endl
+              << "L^3                               = "
+              << pow<3>(L) << std::endl
+              << "L^(3/2)                           = "
+              << pow<static_rational<3,2> >(L) << std::endl
+              << "2vL                               = "
+              << root<2>(L) << std::endl
+              << "(3/2)vL                           = "
+              << root<static_rational<3,2> >(L) << std::endl
+              << std::endl;
+    }
+    
+    {
+    //[quantity_snippet_2
+    quantity<length,std::complex<double> > L(std::complex<double>(3.0,4.0)*meters);
+    quantity<energy,std::complex<double> > E(kilograms*pow<2>(L/seconds));
+    //]
+    
+    std::cout << "L                                 = " << L << std::endl
+              << "L+L                               = " << L+L << std::endl
+              << "L-L                               = " << L-L << std::endl
+              << "L*L                               = " << L*L << std::endl
+              << "L/L                               = " << L/L << std::endl
+              << "L*meter                           = " << L*meter << std::endl
+              << "kilograms*(L/seconds)*(L/seconds) = "
+              << kilograms*(L/seconds)*(L/seconds) << std::endl
+              << "kilograms*(L/seconds)^2           = "
+              << kilograms*pow<2>(L/seconds) << std::endl
+              << "L^3                               = "
+              << pow<3>(L) << std::endl
+              << "L^(3/2)                           = "
+              << pow<static_rational<3,2> >(L) << std::endl
+              << "2vL                               = "
+              << root<2>(L) << std::endl
+              << "(3/2)vL                           = "
+              << root<static_rational<3,2> >(L) << std::endl
+              << std::endl;
+    }
+
+    return 0;
+}
diff --git a/example/quaternion.cpp b/example/quaternion.cpp
new file mode 100644
index 0000000..a2e3e91
--- /dev/null
+++ b/example/quaternion.cpp
@@ -0,0 +1,232 @@
+// Boost.Units - A C++ library for zero-overhead dimensional analysis and 
+// unit/quantity manipulation and conversion
+//
+// Copyright (C) 2003-2008 Matthias Christian Schabel
+// Copyright (C) 2007-2008 Steven Watanabe
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+/** 
+\file
+    
+\brief quaternion.cpp
+
+\details
+Demonstrate interoperability with Boost.Quaternion.
+
+Output:
+@verbatim
+
+//[quaternion_output_1
++L      = (4,3,2,1) m
+-L      = (-4,-3,-2,-1) m
+L+L     = (8,6,4,2) m
+L-L     = (0,0,0,0) m
+L*L     = (2,24,16,8) m^2
+L/L     = (1,0,0,0) dimensionless 
+L^3     = (-104,102,68,34) m^3
+//]
+
+//[quaternion_output_2
++L      = (4 m,3 m,2 m,1 m)
+-L      = (-4 m,-3 m,-2 m,-1 m)
+L+L     = (8 m,6 m,4 m,2 m)
+L-L     = (0 m,0 m,0 m,0 m)
+L^3     = (-104 m^3,102 m^3,68 m^3,34 m^3)
+//]
+
+@endverbatim
+**/
+
+#include <iostream>
+
+#include <boost/math/quaternion.hpp>
+#include <boost/mpl/list.hpp>
+
+#include <boost/units/pow.hpp>
+#include <boost/units/quantity.hpp>
+#include <boost/units/io.hpp>
+
+#include "test_system.hpp"
+
+#if BOOST_UNITS_HAS_BOOST_TYPEOF
+
+#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
+
+BOOST_TYPEOF_REGISTER_TEMPLATE(boost::math::quaternion, 1)
+
+#endif
+
+namespace boost {
+
+namespace units {
+
+//[quaternion_class_snippet_1a
+/// specialize power typeof helper
+template<class Y,long N,long D> 
+struct power_typeof_helper<boost::math::quaternion<Y>,static_rational<N,D> >
+{ 
+    // boost::math::quaternion only supports integer powers
+    BOOST_STATIC_ASSERT(D==1);
+    
+    typedef boost::math::quaternion<
+        typename power_typeof_helper<Y,static_rational<N,D> >::type
+    > type; 
+    
+    static type value(const boost::math::quaternion<Y>& x)  
+    {   
+        return boost::math::pow(x,static_cast<int>(N));
+    }
+};
+//]
+
+//[quaternion_class_snippet_1b
+/// specialize root typeof helper
+template<class Y,long N,long D> 
+struct root_typeof_helper<boost::math::quaternion<Y>,static_rational<N,D> >
+{ 
+    // boost::math::quaternion only supports integer powers
+    BOOST_STATIC_ASSERT(N==1);
+    
+    typedef boost::math::quaternion<
+        typename root_typeof_helper<Y,static_rational<N,D> >::type
+    > type; 
+    
+    static type value(const boost::math::quaternion<Y>& x)  
+    { 
+        return boost::math::pow(x,static_cast<int>(D));
+    }
+};
+//]
+
+//[quaternion_class_snippet_2a
+/// specialize power typeof helper for quaternion<quantity<Unit,Y> >
+template<class Unit,long N,long D,class Y> 
+struct power_typeof_helper<
+    boost::math::quaternion<quantity<Unit,Y> >,
+    static_rational<N,D> >                
+{ 
+    typedef typename power_typeof_helper<
+        Y,
+        static_rational<N,D>
+    >::type     value_type;
+
+    typedef typename power_typeof_helper<
+        Unit,
+        static_rational<N,D>
+    >::type  unit_type;
+
+    typedef quantity<unit_type,value_type>         quantity_type;
+    typedef boost::math::quaternion<quantity_type> type; 
+    
+    static type value(const boost::math::quaternion<quantity<Unit,Y> >& x)  
+    { 
+        const boost::math::quaternion<value_type>   tmp = 
+            pow<static_rational<N,D> >(boost::math::quaternion<Y>(
+                x.R_component_1().value(),
+                x.R_component_2().value(),
+                x.R_component_3().value(),
+                x.R_component_4().value()));
+        
+        return type(quantity_type::from_value(tmp.R_component_1()),
+                    quantity_type::from_value(tmp.R_component_2()),
+                    quantity_type::from_value(tmp.R_component_3()),
+                    quantity_type::from_value(tmp.R_component_4()));
+    }
+};
+//]
+
+//[quaternion_class_snippet_2b
+/// specialize root typeof helper for quaternion<quantity<Unit,Y> >
+template<class Unit,long N,long D,class Y> 
+struct root_typeof_helper<
+    boost::math::quaternion<quantity<Unit,Y> >,
+    static_rational<N,D> >                
+{ 
+    typedef typename root_typeof_helper<
+        Y,
+        static_rational<N,D>
+    >::type      value_type;
+
+    typedef typename root_typeof_helper<
+        Unit,
+        static_rational<N,D>
+    >::type   unit_type;
+
+    typedef quantity<unit_type,value_type>         quantity_type;
+    typedef boost::math::quaternion<quantity_type> type; 
+    
+    static type value(const boost::math::quaternion<quantity<Unit,Y> >& x)  
+    { 
+        const boost::math::quaternion<value_type>   tmp = 
+            root<static_rational<N,D> >(boost::math::quaternion<Y>(
+                x.R_component_1().value(),
+                x.R_component_2().value(),
+                x.R_component_3().value(),
+                x.R_component_4().value()));
+        
+        return type(quantity_type::from_value(tmp.R_component_1()),
+                    quantity_type::from_value(tmp.R_component_2()),
+                    quantity_type::from_value(tmp.R_component_3()),
+                    quantity_type::from_value(tmp.R_component_4()));
+    }
+};
+//]
+
+} // namespace units
+
+} // namespace boost
+
+int main(void)
+{
+    using boost::math::quaternion;
+    using namespace boost::units;
+    using namespace boost::units::test;
+    using boost::units::pow;
+    
+    {
+    //[quaternion_snippet_1
+    typedef quantity<length,quaternion<double> >     length_dimension;
+        
+    length_dimension    L(quaternion<double>(4.0,3.0,2.0,1.0)*meters);
+    //]
+    
+    std::cout << "+L      = " << +L << std::endl
+              << "-L      = " << -L << std::endl
+              << "L+L     = " << L+L << std::endl
+              << "L-L     = " << L-L << std::endl
+              << "L*L     = " << L*L << std::endl
+              << "L/L     = " << L/L << std::endl
+              // unfortunately, without qualification msvc still
+              // finds boost::math::pow by ADL.
+              << "L^3     = " << boost::units::pow<3>(L) << std::endl
+//              << "L^(3/2) = " << pow< static_rational<3,2> >(L) << std::endl
+//              << "3vL     = " << root<3>(L) << std::endl
+//              << "(3/2)vL = " << root< static_rational<3,2> >(L) << std::endl
+              << std::endl;
+    }
+    
+    {
+    //[quaternion_snippet_2
+    typedef quaternion<quantity<length> >     length_dimension;
+        
+    length_dimension    L(4.0*meters,3.0*meters,2.0*meters,1.0*meters);
+    //]
+    
+    std::cout << "+L      = " << +L << std::endl
+              << "-L      = " << -L << std::endl
+              << "L+L     = " << L+L << std::endl
+              << "L-L     = " << L-L << std::endl
+//              << "L*L     = " << L*L << std::endl
+//              << "L/L     = " << L/L << std::endl
+              << "L^3     = " << boost::units::pow<3>(L) << std::endl
+//              << "L^(3/2) = " << pow< static_rational<3,2> >(L) << std::endl
+//              << "3vL     = " << root<3>(L) << std::endl
+//              << "(3/2)vL = " << root< static_rational<3,2> >(L) << std::endl
+              << std::endl;
+    }
+
+    return 0;
+}
diff --git a/example/radar_beam_height.cpp b/example/radar_beam_height.cpp
new file mode 100644
index 0000000..00f1f90
--- /dev/null
+++ b/example/radar_beam_height.cpp
@@ -0,0 +1,167 @@
+// Boost.Units - A C++ library for zero-overhead dimensional analysis and 
+// unit/quantity manipulation and conversion
+//
+// Copyright (C) 2003-2008 Matthias Christian Schabel
+// Copyright (C) 2008 Steven Watanabe
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+/** 
+\file
+    
+\brief radar_beam_height.cpp
+
+\details
+Demonstrate library usage for user test cases suggested by Michael Fawcett.
+
+Output:
+@verbatim
+
+//[radar_beam_height_output
+radar range        : 300 nmi
+earth radius       : 6.37101e+06 m
+beam height 1      : 18169.7 m
+beam height 2      : 9.81085 nmi
+beam height 3      : 18169.7 m
+beam height 4      : 9.81085 nmi
+beam height approx : 59488.4 ft
+beam height approx : 18132.1 m
+//]
+
+@endverbatim
+**/
+
+#include <iostream>
+
+#include <boost/units/conversion.hpp>
+#include <boost/units/io.hpp>
+#include <boost/units/pow.hpp>
+#include <boost/units/systems/si.hpp>
+#include <boost/units/systems/si/prefixes.hpp>
+
+using boost::units::length_dimension;
+using boost::units::pow;
+using boost::units::root;
+using boost::units::quantity;
+using boost::units::unit;
+
+//[radar_beam_height_class_snippet_1
+namespace nautical {
+
+struct length_base_unit : 
+    boost::units::base_unit<length_base_unit, length_dimension, 1>
+{
+    static std::string name()       { return "nautical mile"; }
+    static std::string symbol()     { return "nmi"; }
+};
+
+typedef boost::units::make_system<length_base_unit>::type system;
+
+/// unit typedefs
+typedef unit<length_dimension,system>    length;
+
+static const length mile,miles;
+
+} // namespace nautical
+
+// helper for conversions between nautical length and si length
+BOOST_UNITS_DEFINE_CONVERSION_FACTOR(nautical::length_base_unit,
+                                     boost::units::si::meter_base_unit,
+                                     double, 1.852e3);
+//]
+
+//[radar_beam_height_class_snippet_2
+namespace imperial {
+
+struct length_base_unit : 
+    boost::units::base_unit<length_base_unit, length_dimension, 2>
+{
+    static std::string name()       { return "foot"; }
+    static std::string symbol()     { return "ft"; }
+};
+
+typedef boost::units::make_system<length_base_unit>::type system;
+
+/// unit typedefs
+typedef unit<length_dimension,system>    length;
+
+static const length foot,feet;
+
+} // imperial
+
+// helper for conversions between imperial length and si length
+BOOST_UNITS_DEFINE_CONVERSION_FACTOR(imperial::length_base_unit,
+                                     boost::units::si::meter_base_unit,
+                                     double, 1.0/3.28083989501312);
+//]
+
+// radar beam height functions
+//[radar_beam_height_function_snippet_1
+template<class System,typename T>
+constexpr
+quantity<unit<boost::units::length_dimension,System>,T>
+radar_beam_height(const quantity<unit<length_dimension,System>,T>& radar_range,
+                  const quantity<unit<length_dimension,System>,T>& earth_radius,
+                  T k = 4.0/3.0)
+{
+    return quantity<unit<length_dimension,System>,T>
+        (pow<2>(radar_range)/(2.0*k*earth_radius));
+}
+//]
+
+//[radar_beam_height_function_snippet_2
+template<class return_type,class System1,class System2,typename T>
+constexpr
+return_type
+radar_beam_height(const quantity<unit<length_dimension,System1>,T>& radar_range,
+                  const quantity<unit<length_dimension,System2>,T>& earth_radius,
+                  T k = 4.0/3.0)
+{
+    // need to decide which system to use for calculation
+    return pow<2>(static_cast<return_type>(radar_range))
+            / (2.0*k*static_cast<return_type>(earth_radius));
+}
+//]
+
+//[radar_beam_height_function_snippet_3
+constexpr
+quantity<imperial::length>
+radar_beam_height(const quantity<nautical::length>& range)
+{
+    return quantity<imperial::length>
+        (pow<2>(range/(1.23*nautical::miles/root<2>(imperial::feet))));
+}
+//]
+
+int main(void)
+{
+    using namespace boost::units;
+    using namespace boost::units::si;
+    using namespace nautical;
+
+    //[radar_beam_height_snippet_1
+    const quantity<nautical::length> radar_range(300.0*miles);
+    const quantity<si::length>       earth_radius(6371.0087714*kilo*meters);
+    
+    const quantity<si::length>       beam_height_1(radar_beam_height(quantity<si::length>(radar_range),earth_radius));
+    const quantity<nautical::length> beam_height_2(radar_beam_height(radar_range,quantity<nautical::length>(earth_radius)));
+    const quantity<si::length>       beam_height_3(radar_beam_height< quantity<si::length> >(radar_range,earth_radius));
+    const quantity<nautical::length> beam_height_4(radar_beam_height< quantity<nautical::length> >(radar_range,earth_radius));
+    //]
+    
+    std::cout << "radar range        : " << radar_range << std::endl
+              << "earth radius       : " << earth_radius << std::endl
+              << "beam height 1      : " << beam_height_1 << std::endl
+              << "beam height 2      : " << beam_height_2 << std::endl
+              << "beam height 3      : " << beam_height_3 << std::endl
+              << "beam height 4      : " << beam_height_4 << std::endl
+              << "beam height approx : " << radar_beam_height(radar_range)
+              << std::endl
+              << "beam height approx : "
+              << quantity<si::length>(radar_beam_height(radar_range))
+              << std::endl << std::endl;
+
+    return 0;
+}
diff --git a/example/runtime_conversion_factor.cpp b/example/runtime_conversion_factor.cpp
new file mode 100644
index 0000000..f814c88
--- /dev/null
+++ b/example/runtime_conversion_factor.cpp
@@ -0,0 +1,72 @@
+// Boost.Units - A C++ library for zero-overhead dimensional analysis and 
+// unit/quantity manipulation and conversion
+//
+// Copyright (C) 2003-2008 Matthias Christian Schabel
+// Copyright (C) 2008 Steven Watanabe
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/units/base_dimension.hpp>
+#include <boost/units/base_unit.hpp>
+#include <boost/units/unit.hpp>
+#include <boost/units/quantity.hpp>
+
+//[runtime_conversion_factor_snippet_1
+
+using boost::units::base_dimension;
+using boost::units::base_unit;
+
+static const long currency_base = 1;
+
+struct currency_base_dimension : base_dimension<currency_base_dimension, 1> {};
+
+typedef currency_base_dimension::dimension_type currency_type;
+
+template<long N>
+struct currency_base_unit :
+    base_unit<currency_base_unit<N>, currency_type, currency_base + N> {};
+
+typedef currency_base_unit<0> us_dollar_base_unit;
+typedef currency_base_unit<1> euro_base_unit;
+
+typedef us_dollar_base_unit::unit_type us_dollar;
+typedef euro_base_unit::unit_type euro;
+
+// an array of all possible conversions
+double conversion_factors[2][2] = {
+    {1.0, 1.0},
+    {1.0, 1.0}
+};
+
+double get_conversion_factor(long from, long to) {
+    return(conversion_factors[from][to]);
+}
+
+void set_conversion_factor(long from, long to, double value) {
+    conversion_factors[from][to] = value;
+    conversion_factors[to][from] = 1.0 / value;
+}
+
+BOOST_UNITS_DEFINE_CONVERSION_FACTOR_TEMPLATE((long N1)(long N2),
+    currency_base_unit<N1>,
+    currency_base_unit<N2>,
+    double, get_conversion_factor(N1, N2));
+
+//]
+
+int main() {
+    boost::units::quantity<us_dollar> dollars = 2.00 * us_dollar();
+    boost::units::quantity<euro> euros(dollars);
+    set_conversion_factor(0, 1, 2.0);
+    dollars = static_cast<boost::units::quantity<us_dollar> >(euros);
+    set_conversion_factor(0, 1, .5);
+    euros = static_cast<boost::units::quantity<euro> >(dollars);
+    double value = euros.value(); // = .5
+    if(value != .5) {
+        return(1);
+    } else {
+        return(0);
+    }
+}
diff --git a/example/runtime_unit.cpp b/example/runtime_unit.cpp
new file mode 100644
index 0000000..5777fac
--- /dev/null
+++ b/example/runtime_unit.cpp
@@ -0,0 +1,116 @@
+// Boost.Units - A C++ library for zero-overhead dimensional analysis and 
+// unit/quantity manipulation and conversion
+//
+// Copyright (C) 2003-2008 Matthias Christian Schabel
+// Copyright (C) 2008 Steven Watanabe
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <map>
+#include <iostream>
+#include <boost/lexical_cast.hpp>
+#include <boost/units/quantity.hpp>
+#include <boost/units/cmath.hpp>
+#include <boost/units/systems/si/length.hpp>
+#include <boost/units/base_units/imperial/foot.hpp>
+
+//[runtime_unit_snippet_1
+
+namespace {
+
+using namespace boost::units;
+using imperial::foot_base_unit;
+
+std::map<std::string, quantity<si::length> > known_units;
+
+}
+
+quantity<si::length> calculate(const quantity<si::length>& t) 
+{
+    return(boost::units::hypot(t, 2.0 * si::meters));
+}
+
+int main() 
+{
+    known_units["meter"] = 1.0 * si::meters;
+    known_units["centimeter"] = .01 * si::meters;
+    known_units["foot"] =
+        conversion_factor(foot_base_unit::unit_type(), si::meter) * si::meter;
+        
+    std::string output_type("meter");
+    std::string input;
+    
+    while((std::cout << "> ") && (std::cin >> input)) 
+    {
+        if(!input.empty() && input[0] == '#') 
+        {
+            std::getline(std::cin, input);
+        }
+        else if(input == "exit") 
+        {
+            break;
+        }
+        else if(input == "help") 
+        {
+            std::cout << "type \"exit\" to exit\n"
+                "type \"return 'unit'\" to set the return units\n"
+                "type \"'number' 'unit'\" to do a simple calculation"
+                << std::endl;
+        } 
+        else if(input == "return") 
+        {
+            if(std::cin >> input) 
+            {
+                if(known_units.find(input) != known_units.end()) 
+                {
+                    output_type = input;
+                    std::cout << "Done." << std::endl;
+                } 
+                else 
+                {
+                    std::cout << "Unknown unit \"" << input << "\""
+                         << std::endl;
+                }
+            } 
+            else 
+            {
+                break;
+            }
+        } 
+        else 
+        {
+            try 
+            {
+                double value = boost::lexical_cast<double>(input);
+                
+                if(std::cin >> input) 
+                {
+                    if(known_units.find(input) != known_units.end()) 
+                    {
+                        std::cout << static_cast<double>(
+                            calculate(value * known_units[input]) /
+                            known_units[output_type])
+                            << ' ' << output_type << std::endl;
+                    } 
+                    else 
+                    {
+                        std::cout << "Unknown unit \"" << input << "\""
+                            << std::endl;
+                    }
+                } 
+                else 
+                {
+                    break;
+                }
+            } 
+            catch(...) 
+            {
+                std::cout << "Input error" << std::endl;
+            }
+        }
+    }
+}
+
+//]
diff --git a/example/runtime_unit_input.txt b/example/runtime_unit_input.txt
new file mode 100644
index 0000000..6c109e6
--- /dev/null
+++ b/example/runtime_unit_input.txt
@@ -0,0 +1,13 @@
+# runtime_unit_input.txt
+#
+# Copyright (c) 2007-2008 Steven Watanabe
+#
+# Distributed under the Boost Software License, Version 1.0. (See
+# accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+
+return foot
+2.0 centimeter
+return centimeter
+3.0 meter
+exit
diff --git a/example/systems.cpp b/example/systems.cpp
new file mode 100644
index 0000000..cbbce74
--- /dev/null
+++ b/example/systems.cpp
@@ -0,0 +1,1072 @@
+// Boost.Units - A C++ library for zero-overhead dimensional analysis and 
+// unit/quantity manipulation and conversion
+//
+// Copyright (C) 2003-2008 Matthias Christian Schabel
+// Copyright (C) 2008 Steven Watanabe
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+/** 
+\file
+    
+\brief systems.cpp
+
+\details
+Test various non-si units
+
+Output:
+@verbatim
+
+@endverbatim
+**/
+
+#define BOOST_UNITS_DEFINE_SINGLE_UNIT_SYSTEM(namespace_,unit_name_,dimension_)              \
+namespace boost {                                                                            \
+namespace units {                                                                            \
+namespace namespace_ {                                                                       \
+typedef make_system<unit_name_ ## _base_unit>::type    unit_name_ ## system_;                \
+typedef unit<dimension_ ## _dimension,unit_name_ ## system_> unit_name_ ## _ ## dimension_;  \
+static constexpr unit_name_ ## _ ## dimension_    unit_name_ ## s;                           \
+}                                                                                            \
+}                                                                                            \
+}                                                                                            \
+
+#include <iostream>
+#include <sstream>
+#include <algorithm>
+
+#include <boost/units/conversion.hpp>
+#include <boost/units/io.hpp>
+#include <boost/units/pow.hpp>
+
+#include <boost/units/systems/cgs.hpp>
+#include <boost/units/systems/si.hpp>
+
+// angle base units
+#include <boost/units/base_units/angle/arcminute.hpp>
+#include <boost/units/base_units/angle/arcsecond.hpp>
+#include <boost/units/base_units/angle/degree.hpp>
+#include <boost/units/base_units/angle/gradian.hpp>
+#include <boost/units/base_units/angle/revolution.hpp>
+#include <boost/units/base_units/angle/radian.hpp>
+#include <boost/units/base_units/angle/steradian.hpp>
+
+BOOST_UNITS_DEFINE_SINGLE_UNIT_SYSTEM(angle,arcminute,plane_angle)
+BOOST_UNITS_DEFINE_SINGLE_UNIT_SYSTEM(angle,arcsecond,plane_angle)
+BOOST_UNITS_DEFINE_SINGLE_UNIT_SYSTEM(angle,degree,plane_angle)
+BOOST_UNITS_DEFINE_SINGLE_UNIT_SYSTEM(angle,gradian,plane_angle)
+BOOST_UNITS_DEFINE_SINGLE_UNIT_SYSTEM(angle,radian,plane_angle)
+BOOST_UNITS_DEFINE_SINGLE_UNIT_SYSTEM(angle,revolution,plane_angle)
+
+BOOST_UNITS_DEFINE_SINGLE_UNIT_SYSTEM(angle,steradian,solid_angle)
+
+// astronomical base units
+#include <boost/units/base_units/astronomical/astronomical_unit.hpp>
+#include <boost/units/base_units/astronomical/light_second.hpp>
+#include <boost/units/base_units/astronomical/light_minute.hpp>
+#include <boost/units/base_units/astronomical/light_hour.hpp>
+#include <boost/units/base_units/astronomical/light_day.hpp>
+#include <boost/units/base_units/astronomical/light_year.hpp>
+#include <boost/units/base_units/astronomical/parsec.hpp>
+
+BOOST_UNITS_DEFINE_SINGLE_UNIT_SYSTEM(astronomical,astronomical_unit,length)
+BOOST_UNITS_DEFINE_SINGLE_UNIT_SYSTEM(astronomical,light_second,length)
+BOOST_UNITS_DEFINE_SINGLE_UNIT_SYSTEM(astronomical,light_minute,length)
+BOOST_UNITS_DEFINE_SINGLE_UNIT_SYSTEM(astronomical,light_hour,length)
+BOOST_UNITS_DEFINE_SINGLE_UNIT_SYSTEM(astronomical,light_day,length)
+BOOST_UNITS_DEFINE_SINGLE_UNIT_SYSTEM(astronomical,light_year,length)
+BOOST_UNITS_DEFINE_SINGLE_UNIT_SYSTEM(astronomical,parsec,length)
+
+// imperial base units
+#include <boost/units/base_units/imperial/thou.hpp>
+#include <boost/units/base_units/imperial/inch.hpp>
+#include <boost/units/base_units/imperial/foot.hpp>
+#include <boost/units/base_units/imperial/yard.hpp>
+#include <boost/units/base_units/imperial/furlong.hpp>
+#include <boost/units/base_units/imperial/mile.hpp>
+#include <boost/units/base_units/imperial/league.hpp>
+
+#include <boost/units/base_units/imperial/grain.hpp>
+#include <boost/units/base_units/imperial/drachm.hpp>
+#include <boost/units/base_units/imperial/ounce.hpp>
+#include <boost/units/base_units/imperial/pound.hpp>
+#include <boost/units/base_units/imperial/stone.hpp>
+#include <boost/units/base_units/imperial/quarter.hpp>
+#include <boost/units/base_units/imperial/hundredweight.hpp>
+#include <boost/units/base_units/imperial/ton.hpp>
+
+#include <boost/units/base_units/imperial/fluid_ounce.hpp>
+#include <boost/units/base_units/imperial/gill.hpp>
+#include <boost/units/base_units/imperial/pint.hpp>
+#include <boost/units/base_units/imperial/quart.hpp>
+#include <boost/units/base_units/imperial/gallon.hpp>
+
+#include <boost/units/base_units/imperial/conversions.hpp>
+
+BOOST_UNITS_DEFINE_SINGLE_UNIT_SYSTEM(imperial,thou,length)
+BOOST_UNITS_DEFINE_SINGLE_UNIT_SYSTEM(imperial,inch,length)
+BOOST_UNITS_DEFINE_SINGLE_UNIT_SYSTEM(imperial,foot,length)
+BOOST_UNITS_DEFINE_SINGLE_UNIT_SYSTEM(imperial,yard,length)
+BOOST_UNITS_DEFINE_SINGLE_UNIT_SYSTEM(imperial,furlong,length)
+BOOST_UNITS_DEFINE_SINGLE_UNIT_SYSTEM(imperial,mile,length)
+BOOST_UNITS_DEFINE_SINGLE_UNIT_SYSTEM(imperial,league,length)
+
+BOOST_UNITS_DEFINE_SINGLE_UNIT_SYSTEM(imperial,grain,mass)
+BOOST_UNITS_DEFINE_SINGLE_UNIT_SYSTEM(imperial,drachm,mass)
+BOOST_UNITS_DEFINE_SINGLE_UNIT_SYSTEM(imperial,ounce,mass)
+BOOST_UNITS_DEFINE_SINGLE_UNIT_SYSTEM(imperial,pound,mass)
+BOOST_UNITS_DEFINE_SINGLE_UNIT_SYSTEM(imperial,stone,mass)
+BOOST_UNITS_DEFINE_SINGLE_UNIT_SYSTEM(imperial,quarter,mass)
+BOOST_UNITS_DEFINE_SINGLE_UNIT_SYSTEM(imperial,hundredweight,mass)
+BOOST_UNITS_DEFINE_SINGLE_UNIT_SYSTEM(imperial,ton,mass)
+
+BOOST_UNITS_DEFINE_SINGLE_UNIT_SYSTEM(imperial,fluid_ounce,volume)
+BOOST_UNITS_DEFINE_SINGLE_UNIT_SYSTEM(imperial,gill,volume)
+BOOST_UNITS_DEFINE_SINGLE_UNIT_SYSTEM(imperial,pint,volume)
+BOOST_UNITS_DEFINE_SINGLE_UNIT_SYSTEM(imperial,quart,volume)
+BOOST_UNITS_DEFINE_SINGLE_UNIT_SYSTEM(imperial,gallon,volume)
+
+// metric base units
+#include <boost/units/base_units/metric/angstrom.hpp>
+#include <boost/units/base_units/metric/fermi.hpp>
+#include <boost/units/base_units/metric/micron.hpp>
+#include <boost/units/base_units/metric/nautical_mile.hpp>
+
+#include <boost/units/base_units/metric/ton.hpp>
+
+#include <boost/units/base_units/metric/day.hpp>
+#include <boost/units/base_units/metric/hour.hpp>
+#include <boost/units/base_units/metric/minute.hpp>
+#include <boost/units/base_units/metric/year.hpp>
+
+#include <boost/units/base_units/metric/knot.hpp>
+
+#include <boost/units/base_units/metric/are.hpp>
+#include <boost/units/base_units/metric/barn.hpp>
+#include <boost/units/base_units/metric/hectare.hpp>
+
+#include <boost/units/base_units/metric/liter.hpp>
+
+#include <boost/units/base_units/metric/atmosphere.hpp>
+#include <boost/units/base_units/metric/bar.hpp>
+#include <boost/units/base_units/metric/mmHg.hpp>
+#include <boost/units/base_units/metric/torr.hpp>
+
+BOOST_UNITS_DEFINE_SINGLE_UNIT_SYSTEM(metric,angstrom,length)
+BOOST_UNITS_DEFINE_SINGLE_UNIT_SYSTEM(metric,fermi,length)
+BOOST_UNITS_DEFINE_SINGLE_UNIT_SYSTEM(metric,micron,length)
+BOOST_UNITS_DEFINE_SINGLE_UNIT_SYSTEM(metric,nautical_mile,length)
+
+BOOST_UNITS_DEFINE_SINGLE_UNIT_SYSTEM(metric,ton,mass)
+
+BOOST_UNITS_DEFINE_SINGLE_UNIT_SYSTEM(metric,day,time)
+BOOST_UNITS_DEFINE_SINGLE_UNIT_SYSTEM(metric,hour,time)
+BOOST_UNITS_DEFINE_SINGLE_UNIT_SYSTEM(metric,minute,time)
+BOOST_UNITS_DEFINE_SINGLE_UNIT_SYSTEM(metric,year,time)
+
+BOOST_UNITS_DEFINE_SINGLE_UNIT_SYSTEM(metric,knot,velocity)
+
+BOOST_UNITS_DEFINE_SINGLE_UNIT_SYSTEM(metric,are,area)
+BOOST_UNITS_DEFINE_SINGLE_UNIT_SYSTEM(metric,barn,area)
+BOOST_UNITS_DEFINE_SINGLE_UNIT_SYSTEM(metric,hectare,area)
+
+BOOST_UNITS_DEFINE_SINGLE_UNIT_SYSTEM(metric,liter,volume)
+
+BOOST_UNITS_DEFINE_SINGLE_UNIT_SYSTEM(metric,atmosphere,pressure)
+BOOST_UNITS_DEFINE_SINGLE_UNIT_SYSTEM(metric,bar,pressure)
+BOOST_UNITS_DEFINE_SINGLE_UNIT_SYSTEM(metric,mmHg,pressure)
+BOOST_UNITS_DEFINE_SINGLE_UNIT_SYSTEM(metric,torr,pressure)
+
+// us base units
+
+#include <boost/units/base_units/us/mil.hpp>
+#include <boost/units/base_units/us/inch.hpp>
+#include <boost/units/base_units/us/foot.hpp>
+#include <boost/units/base_units/us/yard.hpp>
+#include <boost/units/base_units/us/mile.hpp>
+
+#include <boost/units/base_units/us/grain.hpp>
+#include <boost/units/base_units/us/dram.hpp>
+#include <boost/units/base_units/us/ounce.hpp>
+#include <boost/units/base_units/us/pound.hpp>
+#include <boost/units/base_units/us/hundredweight.hpp>
+#include <boost/units/base_units/us/ton.hpp>
+
+#include <boost/units/base_units/us/minim.hpp>
+#include <boost/units/base_units/us/fluid_dram.hpp>
+#include <boost/units/base_units/us/teaspoon.hpp>
+#include <boost/units/base_units/us/tablespoon.hpp>
+#include <boost/units/base_units/us/fluid_ounce.hpp>
+#include <boost/units/base_units/us/gill.hpp>
+#include <boost/units/base_units/us/cup.hpp>
+#include <boost/units/base_units/us/pint.hpp>
+#include <boost/units/base_units/us/quart.hpp>
+#include <boost/units/base_units/us/gallon.hpp>
+
+BOOST_UNITS_DEFINE_SINGLE_UNIT_SYSTEM(us,mil,length)
+BOOST_UNITS_DEFINE_SINGLE_UNIT_SYSTEM(us,inch,length)
+BOOST_UNITS_DEFINE_SINGLE_UNIT_SYSTEM(us,foot,length)
+BOOST_UNITS_DEFINE_SINGLE_UNIT_SYSTEM(us,yard,length)
+BOOST_UNITS_DEFINE_SINGLE_UNIT_SYSTEM(us,mile,length)
+
+BOOST_UNITS_DEFINE_SINGLE_UNIT_SYSTEM(us,grain,mass)
+BOOST_UNITS_DEFINE_SINGLE_UNIT_SYSTEM(us,dram,mass)
+BOOST_UNITS_DEFINE_SINGLE_UNIT_SYSTEM(us,ounce,mass)
+BOOST_UNITS_DEFINE_SINGLE_UNIT_SYSTEM(us,pound,mass)
+BOOST_UNITS_DEFINE_SINGLE_UNIT_SYSTEM(us,hundredweight,mass)
+BOOST_UNITS_DEFINE_SINGLE_UNIT_SYSTEM(us,ton,mass)
+
+BOOST_UNITS_DEFINE_SINGLE_UNIT_SYSTEM(us,minim,volume)
+BOOST_UNITS_DEFINE_SINGLE_UNIT_SYSTEM(us,fluid_dram,volume)
+BOOST_UNITS_DEFINE_SINGLE_UNIT_SYSTEM(us,teaspoon,volume)
+BOOST_UNITS_DEFINE_SINGLE_UNIT_SYSTEM(us,tablespoon,volume)
+BOOST_UNITS_DEFINE_SINGLE_UNIT_SYSTEM(us,fluid_ounce,volume)
+BOOST_UNITS_DEFINE_SINGLE_UNIT_SYSTEM(us,gill,volume)
+BOOST_UNITS_DEFINE_SINGLE_UNIT_SYSTEM(us,cup,volume)
+BOOST_UNITS_DEFINE_SINGLE_UNIT_SYSTEM(us,pint,volume)
+BOOST_UNITS_DEFINE_SINGLE_UNIT_SYSTEM(us,quart,volume)
+BOOST_UNITS_DEFINE_SINGLE_UNIT_SYSTEM(us,gallon,volume)
+
+int main(void)
+{
+    using namespace boost::units;
+    
+    {
+        using namespace boost::units::angle;
+        
+        std::cout << "Testing angle base units..." << std::endl;
+        
+        quantity<arcsecond_plane_angle>        as(1.0*arcseconds);
+        quantity<arcminute_plane_angle>        am(1.0*arcminutes);
+        quantity<degree_plane_angle>        d(1.0*degrees);
+        quantity<gradian_plane_angle>        g(1.0*gradians);
+        quantity<radian_plane_angle>        r(1.0*radians);
+        quantity<revolution_plane_angle>    rev(1.0*revolutions);
+        
+        std::cout << as << " = " << quantity<si::plane_angle>(as) << std::endl
+                  << am << " = " << quantity<si::plane_angle>(am) << std::endl
+                  << d << " = " << quantity<si::plane_angle>(d) << std::endl
+                  << g << " = " << quantity<si::plane_angle>(g) << std::endl
+                  << r << " = " << quantity<si::plane_angle>(r) << std::endl
+                  << rev << " = " << quantity<si::plane_angle>(rev) << std::endl
+                  << std::endl;
+    
+        std::cout << rev << "/" << as << " = " << quantity<si::dimensionless>(rev/as) << std::endl
+                  << rev << "/" << am << " = " << quantity<si::dimensionless>(rev/am) << std::endl
+                  << rev << "/" << d << " = " << quantity<si::dimensionless>(rev/d) << std::endl
+                  << rev << "/" << g << " = " << quantity<si::dimensionless>(rev/g) << std::endl
+                  << rev << "/" << r << " = " << quantity<si::dimensionless>(rev/r) << std::endl
+                  << std::endl;
+                  
+        // conversions only work with exponent of +/- 1 in scaled_base_unit?
+        std::cout << as << " = " << quantity<arcsecond_plane_angle>(as) << std::endl
+                  << am << " = " << quantity<arcsecond_plane_angle>(am) << std::endl
+                  << d << " = " << quantity<arcsecond_plane_angle>(d) << std::endl
+                  << rev << " = " << quantity<arcsecond_plane_angle>(rev) << std::endl
+                  << std::endl;
+                  
+        // conversions only work with exponent of +/- 1 in scaled_base_unit? see arcsecond.hpp
+        std::cout << as << " = " << quantity<arcminute_plane_angle>(as) << std::endl
+                  << am << " = " << quantity<arcminute_plane_angle>(am) << std::endl
+                  << d << " = " << quantity<arcminute_plane_angle>(d) << std::endl
+                  << rev << " = " << quantity<arcminute_plane_angle>(rev) << std::endl
+                  << std::endl;
+
+        std::cout << as << " = " << quantity<degree_plane_angle>(as) << std::endl
+                  << am << " = " << quantity<degree_plane_angle>(am) << std::endl
+                  << d << " = " << quantity<degree_plane_angle>(d) << std::endl
+                  << rev << " = " << quantity<degree_plane_angle>(rev) << std::endl
+                  << std::endl;
+                  
+        std::cout << as << " = " << quantity<revolution_plane_angle>(as) << std::endl
+                  << am << " = " << quantity<revolution_plane_angle>(am) << std::endl
+                  << d << " = " << quantity<revolution_plane_angle>(d) << std::endl
+                  << rev << " = " << quantity<revolution_plane_angle>(rev) << std::endl
+                  << std::endl;
+                  
+        quantity<steradian_solid_angle>        sa1(1.0*steradians);
+        
+        std::cout << sa1 << std::endl
+                  << std::endl;
+    }
+    
+    {
+        using namespace boost::units::astronomical;
+
+        std::cout << "Testing astronomical base units..." << std::endl;
+        
+        quantity<light_second_length>        ls(1.0*light_seconds);
+        quantity<light_minute_length>        lm(1.0*light_minutes);
+        quantity<astronomical_unit_length>    au(1.0*astronomical_units);
+        quantity<light_hour_length>            lh(1.0*light_hours);
+        quantity<light_day_length>            ld(1.0*light_days);
+        quantity<light_year_length>            ly(1.0*light_years);
+        quantity<parsec_length>                ps(1.0*parsecs);
+        
+        std::cout << ls << " = " << quantity<si::length>(ls) << std::endl
+                  << lm << " = " << quantity<si::length>(lm) << std::endl
+                  << au << " = " << quantity<si::length>(au) << std::endl
+                  << lh << " = " << quantity<si::length>(lh) << std::endl
+                  << ld << " = " << quantity<si::length>(ld) << std::endl
+                  << ly << " = " << quantity<si::length>(ly) << std::endl
+                  << ps << " = " << quantity<si::length>(ps) << std::endl
+                  << std::endl;
+                  
+        std::cout << ly << "/" << ls << " = " << quantity<si::dimensionless>(ly/ls) << std::endl
+                  << ly << "/" << lm << " = " << quantity<si::dimensionless>(ly/lm) << std::endl
+                  << ly << "/" << au << " = " << quantity<si::dimensionless>(ly/au) << std::endl
+                  << ly << "/" << lh << " = " << quantity<si::dimensionless>(ly/ld) << std::endl
+                  << ly << "/" << ld << " = " << quantity<si::dimensionless>(ly/lh) << std::endl
+                  << ly << "/" << ps << " = " << quantity<si::dimensionless>(ly/ps) << std::endl
+                  << std::endl;
+                  
+        std::cout << ls << " = " << quantity<light_second_length>(ls) << std::endl
+                  << lm << " = " << quantity<light_second_length>(lm) << std::endl
+                  << lh << " = " << quantity<light_second_length>(lh) << std::endl
+                  << ld << " = " << quantity<light_second_length>(ld) << std::endl
+                  << ly << " = " << quantity<light_second_length>(ly) << std::endl
+                  << std::endl;
+                  
+        std::cout << ls << " = " << quantity<light_minute_length>(ls) << std::endl
+                  << lm << " = " << quantity<light_minute_length>(lm) << std::endl
+                  << lh << " = " << quantity<light_minute_length>(lh) << std::endl
+                  << ld << " = " << quantity<light_minute_length>(ld) << std::endl
+                  << ly << " = " << quantity<light_minute_length>(ly) << std::endl
+                  << std::endl;
+                  
+        std::cout << ls << " = " << quantity<light_hour_length>(ls) << std::endl
+                  << lm << " = " << quantity<light_hour_length>(lm) << std::endl
+                  << lh << " = " << quantity<light_hour_length>(lh) << std::endl
+                  << ld << " = " << quantity<light_hour_length>(ld) << std::endl
+                  << ly << " = " << quantity<light_hour_length>(ly) << std::endl
+                  << std::endl;
+                  
+        std::cout << ls << " = " << quantity<light_day_length>(ls) << std::endl
+                  << lm << " = " << quantity<light_day_length>(lm) << std::endl
+                  << lh << " = " << quantity<light_day_length>(lh) << std::endl
+                  << ld << " = " << quantity<light_day_length>(ld) << std::endl
+                  << ly << " = " << quantity<light_day_length>(ly) << std::endl
+                  << std::endl;
+                  
+        std::cout << ls << " = " << quantity<light_year_length>(ls) << std::endl
+                  << lm << " = " << quantity<light_year_length>(lm) << std::endl
+                  << lh << " = " << quantity<light_year_length>(ld) << std::endl
+                  << ld << " = " << quantity<light_year_length>(lh) << std::endl
+                  << ly << " = " << quantity<light_year_length>(ly) << std::endl
+                  << std::endl;
+    }
+    
+    {
+        using namespace boost::units::imperial;
+        
+        std::cout << "Testing imperial base units..." << std::endl;
+        
+        quantity<thou_length>            iml1(1.0*thous);
+        quantity<inch_length>            iml2(1.0*inchs);
+        quantity<foot_length>            iml3(1.0*foots);
+        quantity<yard_length>            iml4(1.0*yards);
+        quantity<furlong_length>        iml5(1.0*furlongs);
+        quantity<mile_length>            iml6(1.0*miles);
+        quantity<league_length>            iml7(1.0*leagues);
+        
+        std::cout << iml1 << " = " << quantity<si::length>(iml1) << std::endl
+                  << iml2 << " = " << quantity<si::length>(iml2) << std::endl
+                  << iml3 << " = " << quantity<si::length>(iml3) << std::endl
+                  << iml4 << " = " << quantity<si::length>(iml4) << std::endl
+                  << iml5 << " = " << quantity<si::length>(iml5) << std::endl
+                  << iml6 << " = " << quantity<si::length>(iml6) << std::endl
+                  << iml7 << " = " << quantity<si::length>(iml7) << std::endl
+                  << std::endl;
+
+        std::cout << iml7 << "/" << iml1 << " = " << quantity<si::dimensionless>(iml7/iml1) << std::endl
+                  << iml7 << "/" << iml2 << " = " << quantity<si::dimensionless>(iml7/iml2) << std::endl
+                  << iml7 << "/" << iml3 << " = " << quantity<si::dimensionless>(iml7/iml3) << std::endl
+                  << iml7 << "/" << iml4 << " = " << quantity<si::dimensionless>(iml7/iml4) << std::endl
+                  << iml7 << "/" << iml5 << " = " << quantity<si::dimensionless>(iml7/iml5) << std::endl
+                  << iml7 << "/" << iml6 << " = " << quantity<si::dimensionless>(iml7/iml6) << std::endl
+                  << std::endl;
+                  
+        std::cout << iml1 << " = " << quantity<thou_length>(iml1) << std::endl
+                  << iml2 << " = " << quantity<thou_length>(iml2) << std::endl
+                  << iml3 << " = " << quantity<thou_length>(iml3) << std::endl
+                  << iml4 << " = " << quantity<thou_length>(iml4) << std::endl
+                  << iml5 << " = " << quantity<thou_length>(iml5) << std::endl
+                  << iml6 << " = " << quantity<thou_length>(iml6) << std::endl
+                  << iml7 << " = " << quantity<thou_length>(iml7) << std::endl
+                  << std::endl;
+
+        std::cout << iml1 << " = " << quantity<inch_length>(iml1) << std::endl
+                  << iml2 << " = " << quantity<inch_length>(iml2) << std::endl
+                  << iml3 << " = " << quantity<inch_length>(iml3) << std::endl
+                  << iml4 << " = " << quantity<inch_length>(iml4) << std::endl
+                  << iml5 << " = " << quantity<inch_length>(iml5) << std::endl
+                  << iml6 << " = " << quantity<inch_length>(iml6) << std::endl
+                  << iml7 << " = " << quantity<inch_length>(iml7) << std::endl
+                  << std::endl;
+
+        std::cout << iml1 << " = " << quantity<foot_length>(iml1) << std::endl
+                  << iml2 << " = " << quantity<foot_length>(iml2) << std::endl
+                  << iml3 << " = " << quantity<foot_length>(iml3) << std::endl
+                  << iml4 << " = " << quantity<foot_length>(iml4) << std::endl
+                  << iml5 << " = " << quantity<foot_length>(iml5) << std::endl
+                  << iml6 << " = " << quantity<foot_length>(iml6) << std::endl
+                  << iml7 << " = " << quantity<foot_length>(iml7) << std::endl
+                  << std::endl;
+
+        std::cout << iml1 << " = " << quantity<yard_length>(iml1) << std::endl
+                  << iml2 << " = " << quantity<yard_length>(iml2) << std::endl
+                  << iml3 << " = " << quantity<yard_length>(iml3) << std::endl
+                  << iml4 << " = " << quantity<yard_length>(iml4) << std::endl
+                  << iml5 << " = " << quantity<yard_length>(iml5) << std::endl
+                  << iml6 << " = " << quantity<yard_length>(iml6) << std::endl
+                  << iml7 << " = " << quantity<yard_length>(iml7) << std::endl
+                  << std::endl;
+
+        std::cout << iml1 << " = " << quantity<furlong_length>(iml1) << std::endl
+                  << iml2 << " = " << quantity<furlong_length>(iml2) << std::endl
+                  << iml3 << " = " << quantity<furlong_length>(iml3) << std::endl
+                  << iml4 << " = " << quantity<furlong_length>(iml4) << std::endl
+                  << iml5 << " = " << quantity<furlong_length>(iml5) << std::endl
+                  << iml6 << " = " << quantity<furlong_length>(iml6) << std::endl
+                  << iml7 << " = " << quantity<furlong_length>(iml7) << std::endl
+                  << std::endl;
+
+        std::cout << iml1 << " = " << quantity<mile_length>(iml1) << std::endl
+                  << iml2 << " = " << quantity<mile_length>(iml2) << std::endl
+                  << iml3 << " = " << quantity<mile_length>(iml3) << std::endl
+                  << iml4 << " = " << quantity<mile_length>(iml4) << std::endl
+                  << iml5 << " = " << quantity<mile_length>(iml5) << std::endl
+                  << iml6 << " = " << quantity<mile_length>(iml6) << std::endl
+                  << iml7 << " = " << quantity<mile_length>(iml7) << std::endl
+                  << std::endl;
+
+        std::cout << iml1 << " = " << quantity<league_length>(iml1) << std::endl
+                  << iml2 << " = " << quantity<league_length>(iml2) << std::endl
+                  << iml3 << " = " << quantity<league_length>(iml3) << std::endl
+                  << iml4 << " = " << quantity<league_length>(iml4) << std::endl
+                  << iml5 << " = " << quantity<league_length>(iml5) << std::endl
+                  << iml6 << " = " << quantity<league_length>(iml6) << std::endl
+                  << iml7 << " = " << quantity<league_length>(iml7) << std::endl
+                  << std::endl;
+                  
+        quantity<grain_mass>            imm1(1.0*grains);
+        quantity<drachm_mass>            imm2(1.0*drachms);
+        quantity<ounce_mass>            imm3(1.0*ounces);
+        quantity<pound_mass>            imm4(1.0*pounds);
+        quantity<stone_mass>            imm5(1.0*stones);
+        quantity<quarter_mass>            imm6(1.0*quarters);
+        quantity<hundredweight_mass>    imm7(1.0*hundredweights);
+        quantity<ton_mass>                imm8(1.0*tons);
+
+        std::cout << imm1 << " = " << quantity<si::mass>(imm1) << std::endl
+                  << imm2 << " = " << quantity<si::mass>(imm2) << std::endl
+                  << imm3 << " = " << quantity<si::mass>(imm3) << std::endl
+                  << imm4 << " = " << quantity<si::mass>(imm4) << std::endl
+                  << imm5 << " = " << quantity<si::mass>(imm5) << std::endl
+                  << imm6 << " = " << quantity<si::mass>(imm6) << std::endl
+                  << imm7 << " = " << quantity<si::mass>(imm7) << std::endl
+                  << imm8 << " = " << quantity<si::mass>(imm8) << std::endl
+                  << std::endl;
+                  
+        std::cout << imm8 << "/" << imm1 << " = " << quantity<si::dimensionless>(imm8/imm1) << std::endl
+                  << imm8 << "/" << imm2 << " = " << quantity<si::dimensionless>(imm8/imm2) << std::endl
+                  << imm8 << "/" << imm3 << " = " << quantity<si::dimensionless>(imm8/imm3) << std::endl
+                  << imm8 << "/" << imm4 << " = " << quantity<si::dimensionless>(imm8/imm4) << std::endl
+                  << imm8 << "/" << imm5 << " = " << quantity<si::dimensionless>(imm8/imm5) << std::endl
+                  << imm8 << "/" << imm6 << " = " << quantity<si::dimensionless>(imm8/imm6) << std::endl
+                  << imm8 << "/" << imm7 << " = " << quantity<si::dimensionless>(imm8/imm7) << std::endl
+                  << std::endl;
+
+        std::cout << imm1 << " = " << quantity<grain_mass>(imm1) << std::endl
+                  << imm2 << " = " << quantity<grain_mass>(imm2) << std::endl
+                  << imm3 << " = " << quantity<grain_mass>(imm3) << std::endl
+                  << imm4 << " = " << quantity<grain_mass>(imm4) << std::endl
+                  << imm5 << " = " << quantity<grain_mass>(imm5) << std::endl
+                  << imm6 << " = " << quantity<grain_mass>(imm6) << std::endl
+                  << imm7 << " = " << quantity<grain_mass>(imm7) << std::endl
+                  << imm8 << " = " << quantity<grain_mass>(imm8) << std::endl
+                  << std::endl;
+                  
+        std::cout << imm1 << " = " << quantity<drachm_mass>(imm1) << std::endl
+                  << imm2 << " = " << quantity<drachm_mass>(imm2) << std::endl
+                  << imm3 << " = " << quantity<drachm_mass>(imm3) << std::endl
+                  << imm4 << " = " << quantity<drachm_mass>(imm4) << std::endl
+                  << imm5 << " = " << quantity<drachm_mass>(imm5) << std::endl
+                  << imm6 << " = " << quantity<drachm_mass>(imm6) << std::endl
+                  << imm7 << " = " << quantity<drachm_mass>(imm7) << std::endl
+                  << imm8 << " = " << quantity<drachm_mass>(imm8) << std::endl
+                  << std::endl;
+                  
+        std::cout << imm1 << " = " << quantity<ounce_mass>(imm1) << std::endl
+                  << imm2 << " = " << quantity<ounce_mass>(imm2) << std::endl
+                  << imm3 << " = " << quantity<ounce_mass>(imm3) << std::endl
+                  << imm4 << " = " << quantity<ounce_mass>(imm4) << std::endl
+                  << imm5 << " = " << quantity<ounce_mass>(imm5) << std::endl
+                  << imm6 << " = " << quantity<ounce_mass>(imm6) << std::endl
+                  << imm7 << " = " << quantity<ounce_mass>(imm7) << std::endl
+                  << imm8 << " = " << quantity<ounce_mass>(imm8) << std::endl
+                  << std::endl;
+                  
+        std::cout << imm1 << " = " << quantity<pound_mass>(imm1) << std::endl
+                  << imm2 << " = " << quantity<pound_mass>(imm2) << std::endl
+                  << imm3 << " = " << quantity<pound_mass>(imm3) << std::endl
+                  << imm4 << " = " << quantity<pound_mass>(imm4) << std::endl
+                  << imm5 << " = " << quantity<pound_mass>(imm5) << std::endl
+                  << imm6 << " = " << quantity<pound_mass>(imm6) << std::endl
+                  << imm7 << " = " << quantity<pound_mass>(imm7) << std::endl
+                  << imm8 << " = " << quantity<pound_mass>(imm8) << std::endl
+                  << std::endl;
+                  
+        std::cout << imm1 << " = " << quantity<stone_mass>(imm1) << std::endl
+                  << imm2 << " = " << quantity<stone_mass>(imm2) << std::endl
+                  << imm3 << " = " << quantity<stone_mass>(imm3) << std::endl
+                  << imm4 << " = " << quantity<stone_mass>(imm4) << std::endl
+                  << imm5 << " = " << quantity<stone_mass>(imm5) << std::endl
+                  << imm6 << " = " << quantity<stone_mass>(imm6) << std::endl
+                  << imm7 << " = " << quantity<stone_mass>(imm7) << std::endl
+                  << imm8 << " = " << quantity<stone_mass>(imm8) << std::endl
+                  << std::endl;
+                  
+        std::cout << imm1 << " = " << quantity<quarter_mass>(imm1) << std::endl
+                  << imm2 << " = " << quantity<quarter_mass>(imm2) << std::endl
+                  << imm3 << " = " << quantity<quarter_mass>(imm3) << std::endl
+                  << imm4 << " = " << quantity<quarter_mass>(imm4) << std::endl
+                  << imm5 << " = " << quantity<quarter_mass>(imm5) << std::endl
+                  << imm6 << " = " << quantity<quarter_mass>(imm6) << std::endl
+                  << imm7 << " = " << quantity<quarter_mass>(imm7) << std::endl
+                  << imm8 << " = " << quantity<quarter_mass>(imm8) << std::endl
+                  << std::endl;
+                  
+        std::cout << imm1 << " = " << quantity<hundredweight_mass>(imm1) << std::endl
+                  << imm2 << " = " << quantity<hundredweight_mass>(imm2) << std::endl
+                  << imm3 << " = " << quantity<hundredweight_mass>(imm3) << std::endl
+                  << imm4 << " = " << quantity<hundredweight_mass>(imm4) << std::endl
+                  << imm5 << " = " << quantity<hundredweight_mass>(imm5) << std::endl
+                  << imm6 << " = " << quantity<hundredweight_mass>(imm6) << std::endl
+                  << imm7 << " = " << quantity<hundredweight_mass>(imm7) << std::endl
+                  << imm8 << " = " << quantity<hundredweight_mass>(imm8) << std::endl
+                  << std::endl;
+                  
+        std::cout << imm1 << " = " << quantity<ton_mass>(imm1) << std::endl
+                  << imm2 << " = " << quantity<ton_mass>(imm2) << std::endl
+                  << imm3 << " = " << quantity<ton_mass>(imm3) << std::endl
+                  << imm4 << " = " << quantity<ton_mass>(imm4) << std::endl
+                  << imm5 << " = " << quantity<ton_mass>(imm5) << std::endl
+                  << imm6 << " = " << quantity<ton_mass>(imm6) << std::endl
+                  << imm7 << " = " << quantity<ton_mass>(imm7) << std::endl
+                  << imm8 << " = " << quantity<ton_mass>(imm8) << std::endl
+                  << std::endl;
+                  
+        quantity<fluid_ounce_volume>    imv1(1.0*fluid_ounces);
+        quantity<gill_volume>            imv2(1.0*gills);
+        quantity<pint_volume>            imv3(1.0*pints);
+        quantity<quart_volume>            imv4(1.0*quarts);
+        quantity<gallon_volume>            imv5(1.0*gallons);
+        
+        std::cout << imv1 << " = " << quantity<si::volume>(imv1) << std::endl
+                  << imv2 << " = " << quantity<si::volume>(imv2) << std::endl
+                  << imv3 << " = " << quantity<si::volume>(imv3) << std::endl
+                  << imv4 << " = " << quantity<si::volume>(imv4) << std::endl
+                  << imv5 << " = " << quantity<si::volume>(imv5) << std::endl
+                  << std::endl;
+                  
+        std::cout << imv5 << "/" << imv1 << " = " << quantity<si::dimensionless>(imv5/imv1) << std::endl
+                  << imv5 << "/" << imv2 << " = " << quantity<si::dimensionless>(imv5/imv2) << std::endl
+                  << imv5 << "/" << imv3 << " = " << quantity<si::dimensionless>(imv5/imv3) << std::endl
+                  << imv5 << "/" << imv4 << " = " << quantity<si::dimensionless>(imv5/imv4) << std::endl
+                  << std::endl;
+
+        std::cout << imv1 << " = " << quantity<fluid_ounce_volume>(imv1) << std::endl
+                  << imv2 << " = " << quantity<fluid_ounce_volume>(imv2) << std::endl
+                  << imv3 << " = " << quantity<fluid_ounce_volume>(imv3) << std::endl
+                  << imv4 << " = " << quantity<fluid_ounce_volume>(imv4) << std::endl
+                  << imv5 << " = " << quantity<fluid_ounce_volume>(imv5) << std::endl
+                  << std::endl;
+                  
+        std::cout << imv1 << " = " << quantity<gill_volume>(imv1) << std::endl
+                  << imv2 << " = " << quantity<gill_volume>(imv2) << std::endl
+                  << imv3 << " = " << quantity<gill_volume>(imv3) << std::endl
+                  << imv4 << " = " << quantity<gill_volume>(imv4) << std::endl
+                  << imv5 << " = " << quantity<gill_volume>(imv5) << std::endl
+                  << std::endl;
+                  
+        std::cout << imv1 << " = " << quantity<pint_volume>(imv1) << std::endl
+                  << imv2 << " = " << quantity<pint_volume>(imv2) << std::endl
+                  << imv3 << " = " << quantity<pint_volume>(imv3) << std::endl
+                  << imv4 << " = " << quantity<pint_volume>(imv4) << std::endl
+                  << imv5 << " = " << quantity<pint_volume>(imv5) << std::endl
+                  << std::endl;
+                  
+        std::cout << imv1 << " = " << quantity<quart_volume>(imv1) << std::endl
+                  << imv2 << " = " << quantity<quart_volume>(imv2) << std::endl
+                  << imv3 << " = " << quantity<quart_volume>(imv3) << std::endl
+                  << imv4 << " = " << quantity<quart_volume>(imv4) << std::endl
+                  << imv5 << " = " << quantity<quart_volume>(imv5) << std::endl
+                  << std::endl;
+                  
+        std::cout << imv1 << " = " << quantity<gallon_volume>(imv1) << std::endl
+                  << imv2 << " = " << quantity<gallon_volume>(imv2) << std::endl
+                  << imv3 << " = " << quantity<gallon_volume>(imv3) << std::endl
+                  << imv4 << " = " << quantity<gallon_volume>(imv4) << std::endl
+                  << imv5 << " = " << quantity<gallon_volume>(imv5) << std::endl
+                  << std::endl;
+    }
+    
+    {
+        using namespace boost::units::metric;
+        
+        std::cout << "Testing metric base units..." << std::endl;
+        
+        quantity<fermi_length>            ml1(1.0*fermis);
+        quantity<angstrom_length>        ml2(1.0*angstroms);
+        quantity<micron_length>            ml3(1.0*microns);
+        quantity<nautical_mile_length>    ml4(1.0*nautical_miles);
+    
+        std::cout << ml1 << " = " << quantity<si::length>(ml1) << std::endl
+                  << ml2 << " = " << quantity<si::length>(ml2) << std::endl
+                  << ml3 << " = " << quantity<si::length>(ml3) << std::endl
+                  << ml4 << " = " << quantity<si::length>(ml4) << std::endl
+                  << std::endl;
+
+        std::cout << ml4 << "/" << ml1 << " = " << quantity<si::dimensionless>(ml4/ml1) << std::endl
+                  << ml4 << "/" << ml2 << " = " << quantity<si::dimensionless>(ml4/ml2) << std::endl
+                  << ml4 << "/" << ml3 << " = " << quantity<si::dimensionless>(ml4/ml3) << std::endl
+                  << std::endl;
+
+        std::cout << ml1 << " = " << quantity<fermi_length>(ml1) << std::endl
+                  << ml2 << " = " << quantity<fermi_length>(ml2) << std::endl
+                  << ml3 << " = " << quantity<fermi_length>(ml3) << std::endl
+                  << ml4 << " = " << quantity<fermi_length>(ml4) << std::endl
+                  << std::endl;
+
+        std::cout << ml1 << " = " << quantity<angstrom_length>(ml1) << std::endl
+                  << ml2 << " = " << quantity<angstrom_length>(ml2) << std::endl
+                  << ml3 << " = " << quantity<angstrom_length>(ml3) << std::endl
+                  << ml4 << " = " << quantity<angstrom_length>(ml4) << std::endl
+                  << std::endl;
+
+        std::cout << ml1 << " = " << quantity<micron_length>(ml1) << std::endl
+                  << ml2 << " = " << quantity<micron_length>(ml2) << std::endl
+                  << ml3 << " = " << quantity<micron_length>(ml3) << std::endl
+                  << ml4 << " = " << quantity<micron_length>(ml4) << std::endl
+                  << std::endl;
+
+        std::cout << ml1 << " = " << quantity<nautical_mile_length>(ml1) << std::endl
+                  << ml2 << " = " << quantity<nautical_mile_length>(ml2) << std::endl
+                  << ml3 << " = " << quantity<nautical_mile_length>(ml3) << std::endl
+                  << ml4 << " = " << quantity<nautical_mile_length>(ml4) << std::endl
+                  << std::endl;
+
+        quantity<ton_mass>    mm1(1.0*tons);
+        
+        std::cout << mm1 << " = " << quantity<cgs::mass>(mm1) << std::endl
+                  //<< quantity<si::mass>(mm1) << std::endl    // this should work... 
+                  << std::endl;
+                  
+        quantity<minute_time>    mt1(1.0*minutes);
+        quantity<hour_time>        mt2(1.0*hours);
+        quantity<day_time>        mt3(1.0*days);
+        quantity<year_time>        mt4(1.0*years);
+        
+        std::cout << mt1 << " = " << quantity<si::time>(mt1) << std::endl
+                  << mt2 << " = " << quantity<si::time>(mt2) << std::endl
+                  << mt3 << " = " << quantity<si::time>(mt3) << std::endl
+                  << mt4 << " = " << quantity<si::time>(mt4) << std::endl
+                  << std::endl;
+
+        std::cout << mt4 << "/" << mt1 << " = " << quantity<si::dimensionless>(mt4/mt1) << std::endl
+                  << mt4 << "/" << mt2 << " = " << quantity<si::dimensionless>(mt4/mt2) << std::endl
+                  << mt4 << "/" << mt3 << " = " << quantity<si::dimensionless>(mt4/mt3) << std::endl
+                  << std::endl;
+
+        std::cout << mt1 << " = " << quantity<minute_time>(mt1) << std::endl
+                  << mt2 << " = " << quantity<minute_time>(mt2) << std::endl
+                  << mt3 << " = " << quantity<minute_time>(mt3) << std::endl
+                  << mt4 << " = " << quantity<minute_time>(mt4) << std::endl
+                  << std::endl;
+
+        std::cout << mt1 << " = " << quantity<hour_time>(mt1) << std::endl
+                  << mt2 << " = " << quantity<hour_time>(mt2) << std::endl
+                  << mt3 << " = " << quantity<hour_time>(mt3) << std::endl
+                  << mt4 << " = " << quantity<hour_time>(mt4) << std::endl
+                  << std::endl;
+
+        std::cout << mt1 << " = " << quantity<day_time>(mt1) << std::endl
+                  << mt2 << " = " << quantity<day_time>(mt2) << std::endl
+                  << mt3 << " = " << quantity<day_time>(mt3) << std::endl
+                  << mt4 << " = " << quantity<day_time>(mt4) << std::endl
+                  << std::endl;
+
+        std::cout << mt1 << " = " << quantity<year_time>(mt1) << std::endl
+                  << mt2 << " = " << quantity<year_time>(mt2) << std::endl
+                  << mt3 << " = " << quantity<year_time>(mt3) << std::endl
+                  << mt4 << " = " << quantity<year_time>(mt4) << std::endl
+                  << std::endl;
+                          
+        quantity<knot_velocity>    ms1(1.0*knots);
+        
+        std::cout << ms1 << " = " << quantity<si::velocity>(ms1) << std::endl
+                  << std::endl;
+                  
+        quantity<barn_area>        ma1(1.0*barns);
+        quantity<are_area>        ma2(1.0*ares);
+        quantity<hectare_area>    ma3(1.0*hectares);
+        
+        std::cout << ma1 << " = " << quantity<si::area>(ma1) << std::endl
+                  << ma2 << " = " << quantity<si::area>(ma2) << std::endl
+                  << ma3 << " = " << quantity<si::area>(ma3) << std::endl
+                  << std::endl;
+
+        std::cout << ma3 << "/" << ma1 << " = " << quantity<si::dimensionless>(ma3/ma1) << std::endl
+                  << ma3 << "/" << ma2 << " = " << quantity<si::dimensionless>(ma3/ma2) << std::endl
+                  << std::endl;
+
+        std::cout << ma1 << " = " << quantity<barn_area>(ma1) << std::endl
+                  << ma2 << " = " << quantity<barn_area>(ma2) << std::endl
+                  << ma3 << " = " << quantity<barn_area>(ma3) << std::endl
+                  << std::endl;
+
+        std::cout << ma1 << " = " << quantity<are_area>(ma1) << std::endl
+                  << ma2 << " = " << quantity<are_area>(ma2) << std::endl
+                  << ma3 << " = " << quantity<are_area>(ma3) << std::endl
+                  << std::endl;
+
+        std::cout << ma1 << " = " << quantity<hectare_area>(ma1) << std::endl
+                  << ma2 << " = " << quantity<hectare_area>(ma2) << std::endl
+                  << ma3 << " = " << quantity<hectare_area>(ma3) << std::endl
+                  << std::endl;
+        
+        quantity<liter_volume>    mv1(1.0*liters);
+        
+        std::cout << mv1 << " = " << quantity<si::volume>(mv1) << std::endl
+                  << std::endl;
+        
+        quantity<mmHg_pressure>            mp1(1.0*mmHgs);
+        quantity<torr_pressure>            mp2(1.0*torrs);
+        quantity<bar_pressure>            mp3(1.0*bars);
+        quantity<atmosphere_pressure>    mp4(1.0*atmospheres);
+        
+        std::cout << mp1 << " = " << quantity<si::pressure>(mp1) << std::endl
+                  << mp2 << " = " << quantity<si::pressure>(mp2) << std::endl
+                  << mp3 << " = " << quantity<si::pressure>(mp3) << std::endl
+                  << mp4 << " = " << quantity<si::pressure>(mp4) << std::endl
+                  << std::endl;
+
+        std::cout << mp4 << "/" << mp1 << " = " << quantity<si::dimensionless>(mp4/mp1) << std::endl
+                  << mp4 << "/" << mp2  << " = " << quantity<si::dimensionless>(mp4/mp2) << std::endl
+                  << mp4 << "/" << mp3  << " = " << quantity<si::dimensionless>(mp4/mp3) << std::endl
+                  << std::endl;
+
+        std::cout << mp1 << " = " << quantity<mmHg_pressure>(mp1) << std::endl
+                  << mp2 << " = " << quantity<mmHg_pressure>(mp2) << std::endl
+                  << mp3 << " = " << quantity<mmHg_pressure>(mp3) << std::endl
+                  << mp4 << " = " << quantity<mmHg_pressure>(mp4) << std::endl
+                  << std::endl;
+
+        std::cout << mp1 << " = " << quantity<torr_pressure>(mp1) << std::endl
+                  << mp2 << " = " << quantity<torr_pressure>(mp2) << std::endl
+                  << mp3 << " = " << quantity<torr_pressure>(mp3) << std::endl
+                  << mp4 << " = " << quantity<torr_pressure>(mp4) << std::endl
+                  << std::endl;
+
+        std::cout << mp1 << " = " << quantity<bar_pressure>(mp1) << std::endl
+                  << mp2 << " = " << quantity<bar_pressure>(mp2) << std::endl
+                  << mp3 << " = " << quantity<bar_pressure>(mp3) << std::endl
+                  << mp4 << " = " << quantity<bar_pressure>(mp4) << std::endl
+                  << std::endl;
+
+        std::cout << mp1 << " = " << quantity<atmosphere_pressure>(mp1) << std::endl
+                  << mp2 << " = " << quantity<atmosphere_pressure>(mp2) << std::endl
+                  << mp3 << " = " << quantity<atmosphere_pressure>(mp3) << std::endl
+                  << mp4 << " = " << quantity<atmosphere_pressure>(mp4) << std::endl
+                  << std::endl;
+    }
+    
+    {
+        using namespace boost::units::us;
+        
+        std::cout << "Testing U.S. customary base units..." << std::endl;
+        
+        quantity<mil_length>            iml1(1.0*mils);
+        quantity<inch_length>            iml2(1.0*inchs);
+        quantity<foot_length>            iml3(1.0*foots);
+        quantity<yard_length>            iml4(1.0*yards);
+        quantity<mile_length>            iml5(1.0*miles);
+        
+        std::cout << iml1 << " = " << quantity<si::length>(iml1) << std::endl
+                  << iml2 << " = " << quantity<si::length>(iml2) << std::endl
+                  << iml3 << " = " << quantity<si::length>(iml3) << std::endl
+                  << iml4 << " = " << quantity<si::length>(iml4) << std::endl
+                  << iml5 << " = " << quantity<si::length>(iml5) << std::endl
+                  << std::endl;
+
+        std::cout << iml5 << "/" << iml1 << " = " << quantity<si::dimensionless>(iml5/iml1) << std::endl
+                  << iml5 << "/" << iml2 << " = " << quantity<si::dimensionless>(iml5/iml2) << std::endl
+                  << iml5 << "/" << iml3 << " = " << quantity<si::dimensionless>(iml5/iml3) << std::endl
+                  << iml5 << "/" << iml4 << " = " << quantity<si::dimensionless>(iml5/iml4) << std::endl
+                  << std::endl;
+
+        std::cout << iml1 << " = " << quantity<mil_length>(iml1) << std::endl
+                  << iml2 << " = " << quantity<mil_length>(iml2) << std::endl
+                  << iml3 << " = " << quantity<mil_length>(iml3) << std::endl
+                  << iml4 << " = " << quantity<mil_length>(iml4) << std::endl
+                  << iml5 << " = " << quantity<mil_length>(iml5) << std::endl
+                  << std::endl;
+
+        std::cout << iml1 << " = " << quantity<inch_length>(iml1) << std::endl
+                  << iml2 << " = " << quantity<inch_length>(iml2) << std::endl
+                  << iml3 << " = " << quantity<inch_length>(iml3) << std::endl
+                  << iml4 << " = " << quantity<inch_length>(iml4) << std::endl
+                  << iml5 << " = " << quantity<inch_length>(iml5) << std::endl
+                  << std::endl;
+
+        std::cout << iml1 << " = " << quantity<foot_length>(iml1) << std::endl
+                  << iml2 << " = " << quantity<foot_length>(iml2) << std::endl
+                  << iml3 << " = " << quantity<foot_length>(iml3) << std::endl
+                  << iml4 << " = " << quantity<foot_length>(iml4) << std::endl
+                  << iml5 << " = " << quantity<foot_length>(iml5) << std::endl
+                  << std::endl;
+
+        std::cout << iml1 << " = " << quantity<yard_length>(iml1) << std::endl
+                  << iml2 << " = " << quantity<yard_length>(iml2) << std::endl
+                  << iml3 << " = " << quantity<yard_length>(iml3) << std::endl
+                  << iml4 << " = " << quantity<yard_length>(iml4) << std::endl
+                  << iml5 << " = " << quantity<yard_length>(iml5) << std::endl
+                  << std::endl;
+
+        std::cout << iml1 << " = " << quantity<mile_length>(iml1) << std::endl
+                  << iml2 << " = " << quantity<mile_length>(iml2) << std::endl
+                  << iml3 << " = " << quantity<mile_length>(iml3) << std::endl
+                  << iml4 << " = " << quantity<mile_length>(iml4) << std::endl
+                  << iml5 << " = " << quantity<mile_length>(iml5) << std::endl
+                  << std::endl;
+
+        quantity<grain_mass>            imm1(1.0*grains);
+        quantity<dram_mass>                imm2(1.0*drams);
+        quantity<ounce_mass>            imm3(1.0*ounces);
+        quantity<pound_mass>            imm4(1.0*pounds);
+        quantity<hundredweight_mass>    imm5(1.0*hundredweights);
+        quantity<ton_mass>                imm6(1.0*tons);
+
+        std::cout << imm1 << " = " << quantity<si::mass>(imm1) << std::endl
+                  << imm2 << " = " << quantity<si::mass>(imm2) << std::endl
+                  << imm3 << " = " << quantity<si::mass>(imm3) << std::endl
+                  << imm4 << " = " << quantity<si::mass>(imm4) << std::endl
+                  << imm5 << " = " << quantity<si::mass>(imm5) << std::endl
+                  << imm6 << " = " << quantity<si::mass>(imm6) << std::endl
+                  << std::endl;
+                  
+        std::cout << imm6 << "/" << imm1 << " = " << quantity<si::dimensionless>(imm6/imm1) << std::endl
+                  << imm6 << "/" << imm2 << " = " << quantity<si::dimensionless>(imm6/imm2) << std::endl
+                  << imm6 << "/" << imm3 << " = " << quantity<si::dimensionless>(imm6/imm3) << std::endl
+                  << imm6 << "/" << imm4 << " = " << quantity<si::dimensionless>(imm6/imm4) << std::endl
+                  << imm6 << "/" << imm5 << " = " << quantity<si::dimensionless>(imm6/imm5) << std::endl
+                  << std::endl;
+
+        std::cout << imm1 << " = " << quantity<grain_mass>(imm1) << std::endl
+                  << imm2 << " = " << quantity<grain_mass>(imm2) << std::endl
+                  << imm3 << " = " << quantity<grain_mass>(imm3) << std::endl
+                  << imm4 << " = " << quantity<grain_mass>(imm4) << std::endl
+                  << imm5 << " = " << quantity<grain_mass>(imm5) << std::endl
+                  << imm6 << " = " << quantity<grain_mass>(imm6) << std::endl
+                  << std::endl;
+                  
+        std::cout << imm1 << " = " << quantity<dram_mass>(imm1) << std::endl
+                  << imm2 << " = " << quantity<dram_mass>(imm2) << std::endl
+                  << imm3 << " = " << quantity<dram_mass>(imm3) << std::endl
+                  << imm4 << " = " << quantity<dram_mass>(imm4) << std::endl
+                  << imm5 << " = " << quantity<dram_mass>(imm5) << std::endl
+                  << imm6 << " = " << quantity<dram_mass>(imm6) << std::endl
+                  << std::endl;
+                  
+        std::cout << imm1 << " = " << quantity<ounce_mass>(imm1) << std::endl
+                  << imm2 << " = " << quantity<ounce_mass>(imm2) << std::endl
+                  << imm3 << " = " << quantity<ounce_mass>(imm3) << std::endl
+                  << imm4 << " = " << quantity<ounce_mass>(imm4) << std::endl
+                  << imm5 << " = " << quantity<ounce_mass>(imm5) << std::endl
+                  << imm6 << " = " << quantity<ounce_mass>(imm6) << std::endl
+                  << std::endl;
+                  
+        std::cout << imm1 << " = " << quantity<pound_mass>(imm1) << std::endl
+                  << imm2 << " = " << quantity<pound_mass>(imm2) << std::endl
+                  << imm3 << " = " << quantity<pound_mass>(imm3) << std::endl
+                  << imm4 << " = " << quantity<pound_mass>(imm4) << std::endl
+                  << imm5 << " = " << quantity<pound_mass>(imm5) << std::endl
+                  << imm6 << " = " << quantity<pound_mass>(imm6) << std::endl
+                  << std::endl;
+                  
+        std::cout << imm1 << " = " << quantity<hundredweight_mass>(imm1) << std::endl
+                  << imm2 << " = " << quantity<hundredweight_mass>(imm2) << std::endl
+                  << imm3 << " = " << quantity<hundredweight_mass>(imm3) << std::endl
+                  << imm4 << " = " << quantity<hundredweight_mass>(imm4) << std::endl
+                  << imm5 << " = " << quantity<hundredweight_mass>(imm5) << std::endl
+                  << imm6 << " = " << quantity<hundredweight_mass>(imm6) << std::endl
+                  << std::endl;
+                  
+        std::cout << imm1 << " = " << quantity<ton_mass>(imm1) << std::endl
+                  << imm2 << " = " << quantity<ton_mass>(imm2) << std::endl
+                  << imm3 << " = " << quantity<ton_mass>(imm3) << std::endl
+                  << imm4 << " = " << quantity<ton_mass>(imm4) << std::endl
+                  << imm5 << " = " << quantity<ton_mass>(imm5) << std::endl
+                  << imm6 << " = " << quantity<ton_mass>(imm6) << std::endl
+                  << std::endl;
+                  
+        quantity<minim_volume>            imv1(1.0*minims);
+        quantity<fluid_dram_volume>        imv2(1.0*fluid_drams);
+        quantity<teaspoon_volume>        imv3(1.0*teaspoons);
+        quantity<tablespoon_volume>        imv4(1.0*tablespoons);
+        quantity<fluid_ounce_volume>    imv5(1.0*fluid_ounces);
+        quantity<gill_volume>            imv6(1.0*gills);
+        quantity<cup_volume>            imv7(1.0*cups);
+        quantity<pint_volume>            imv8(1.0*pints);
+        quantity<quart_volume>            imv9(1.0*quarts);
+        quantity<gallon_volume>            imv10(1.0*gallons);
+        
+        std::cout << imv1 << " = " << quantity<si::volume>(imv1) << std::endl
+                  << imv2 << " = " << quantity<si::volume>(imv2) << std::endl
+                  << imv3 << " = " << quantity<si::volume>(imv3) << std::endl
+                  << imv4 << " = " << quantity<si::volume>(imv4) << std::endl
+                  << imv5 << " = " << quantity<si::volume>(imv5) << std::endl
+                  << imv6 << " = " << quantity<si::volume>(imv6) << std::endl
+                  << imv7 << " = " << quantity<si::volume>(imv7) << std::endl
+                  << imv8 << " = " << quantity<si::volume>(imv8) << std::endl
+                  << imv9 << " = " << quantity<si::volume>(imv9) << std::endl
+                  << imv10 << " = " << quantity<si::volume>(imv10) << std::endl
+                  << std::endl;
+
+        std::cout << imv10 << "/" << imv1 << " = " << quantity<si::dimensionless>(imv10/imv1) << std::endl
+                  << imv10 << "/" << imv2 << " = " << quantity<si::dimensionless>(imv10/imv2) << std::endl
+                  << imv10 << "/" << imv3 << " = " << quantity<si::dimensionless>(imv10/imv3) << std::endl
+                  << imv10 << "/" << imv4 << " = " << quantity<si::dimensionless>(imv10/imv4) << std::endl
+                  << imv10 << "/" << imv5 << " = " << quantity<si::dimensionless>(imv10/imv5) << std::endl
+                  << imv10 << "/" << imv6 << " = " << quantity<si::dimensionless>(imv10/imv6) << std::endl
+                  << imv10 << "/" << imv7 << " = " << quantity<si::dimensionless>(imv10/imv7) << std::endl
+                  << imv10 << "/" << imv8 << " = " << quantity<si::dimensionless>(imv10/imv8) << std::endl
+                  << imv10 << "/" << imv9 << " = " << quantity<si::dimensionless>(imv10/imv9) << std::endl
+                  << std::endl;
+
+        std::cout << imv1 << " = " << quantity<minim_volume>(imv1) << std::endl
+                  << imv2 << " = " << quantity<minim_volume>(imv2) << std::endl
+                  << imv3 << " = " << quantity<minim_volume>(imv3) << std::endl
+                  << imv4 << " = " << quantity<minim_volume>(imv4) << std::endl
+                  << imv5 << " = " << quantity<minim_volume>(imv5) << std::endl
+                  << imv6 << " = " << quantity<minim_volume>(imv6) << std::endl
+                  << imv7 << " = " << quantity<minim_volume>(imv7) << std::endl
+                  << imv8 << " = " << quantity<minim_volume>(imv8) << std::endl
+                  << imv9 << " = " << quantity<minim_volume>(imv9) << std::endl
+                  << imv10 << " = " << quantity<minim_volume>(imv10) << std::endl
+                  << std::endl;
+
+        std::cout << imv1 << " = " << quantity<fluid_dram_volume>(imv1) << std::endl
+                  << imv2 << " = " << quantity<fluid_dram_volume>(imv2) << std::endl
+                  << imv3 << " = " << quantity<fluid_dram_volume>(imv3) << std::endl
+                  << imv4 << " = " << quantity<fluid_dram_volume>(imv4) << std::endl
+                  << imv5 << " = " << quantity<fluid_dram_volume>(imv5) << std::endl
+                  << imv6 << " = " << quantity<fluid_dram_volume>(imv6) << std::endl
+                  << imv7 << " = " << quantity<fluid_dram_volume>(imv7) << std::endl
+                  << imv8 << " = " << quantity<fluid_dram_volume>(imv8) << std::endl
+                  << imv9 << " = " << quantity<fluid_dram_volume>(imv9) << std::endl
+                  << imv10 << " = " << quantity<fluid_dram_volume>(imv10) << std::endl
+                  << std::endl;
+
+        std::cout << imv1 << " = " << quantity<teaspoon_volume>(imv1) << std::endl
+                  << imv2 << " = " << quantity<teaspoon_volume>(imv2) << std::endl
+                  << imv3 << " = " << quantity<teaspoon_volume>(imv3) << std::endl
+                  << imv4 << " = " << quantity<teaspoon_volume>(imv4) << std::endl
+                  << imv5 << " = " << quantity<teaspoon_volume>(imv5) << std::endl
+                  << imv6 << " = " << quantity<teaspoon_volume>(imv6) << std::endl
+                  << imv7 << " = " << quantity<teaspoon_volume>(imv7) << std::endl
+                  << imv8 << " = " << quantity<teaspoon_volume>(imv8) << std::endl
+                  << imv9 << " = " << quantity<teaspoon_volume>(imv9) << std::endl
+                  << imv10 << " = " << quantity<teaspoon_volume>(imv10) << std::endl
+                  << std::endl;
+
+        std::cout << imv1 << " = " << quantity<tablespoon_volume>(imv1) << std::endl
+                  << imv2 << " = " << quantity<tablespoon_volume>(imv2) << std::endl
+                  << imv3 << " = " << quantity<tablespoon_volume>(imv3) << std::endl
+                  << imv4 << " = " << quantity<tablespoon_volume>(imv4) << std::endl
+                  << imv5 << " = " << quantity<tablespoon_volume>(imv5) << std::endl
+                  << imv6 << " = " << quantity<tablespoon_volume>(imv6) << std::endl
+                  << imv7 << " = " << quantity<tablespoon_volume>(imv7) << std::endl
+                  << imv8 << " = " << quantity<tablespoon_volume>(imv8) << std::endl
+                  << imv9 << " = " << quantity<tablespoon_volume>(imv9) << std::endl
+                  << imv10 << " = " << quantity<tablespoon_volume>(imv10) << std::endl
+                  << std::endl;
+
+        std::cout << imv1 << " = " << quantity<fluid_ounce_volume>(imv1) << std::endl
+                  << imv2 << " = " << quantity<fluid_ounce_volume>(imv2) << std::endl
+                  << imv3 << " = " << quantity<fluid_ounce_volume>(imv3) << std::endl
+                  << imv4 << " = " << quantity<fluid_ounce_volume>(imv4) << std::endl
+                  << imv5 << " = " << quantity<fluid_ounce_volume>(imv5) << std::endl
+                  << imv6 << " = " << quantity<fluid_ounce_volume>(imv6) << std::endl
+                  << imv7 << " = " << quantity<fluid_ounce_volume>(imv7) << std::endl
+                  << imv8 << " = " << quantity<fluid_ounce_volume>(imv8) << std::endl
+                  << imv9 << " = " << quantity<fluid_ounce_volume>(imv9) << std::endl
+                  << imv10 << " = " << quantity<fluid_ounce_volume>(imv10) << std::endl
+                  << std::endl;
+
+        std::cout << imv1 << " = " << quantity<gill_volume>(imv1) << std::endl
+                  << imv2 << " = " << quantity<gill_volume>(imv2) << std::endl
+                  << imv3 << " = " << quantity<gill_volume>(imv3) << std::endl
+                  << imv4 << " = " << quantity<gill_volume>(imv4) << std::endl
+                  << imv5 << " = " << quantity<gill_volume>(imv5) << std::endl
+                  << imv6 << " = " << quantity<gill_volume>(imv6) << std::endl
+                  << imv7 << " = " << quantity<gill_volume>(imv7) << std::endl
+                  << imv8 << " = " << quantity<gill_volume>(imv8) << std::endl
+                  << imv9 << " = " << quantity<gill_volume>(imv9) << std::endl
+                  << imv10 << " = " << quantity<gill_volume>(imv10) << std::endl
+                  << std::endl;
+
+        std::cout << imv1 << " = " << quantity<cup_volume>(imv1) << std::endl
+                  << imv2 << " = " << quantity<cup_volume>(imv2) << std::endl
+                  << imv3 << " = " << quantity<cup_volume>(imv3) << std::endl
+                  << imv4 << " = " << quantity<cup_volume>(imv4) << std::endl
+                  << imv5 << " = " << quantity<cup_volume>(imv5) << std::endl
+                  << imv6 << " = " << quantity<cup_volume>(imv6) << std::endl
+                  << imv7 << " = " << quantity<cup_volume>(imv7) << std::endl
+                  << imv8 << " = " << quantity<cup_volume>(imv8) << std::endl
+                  << imv9 << " = " << quantity<cup_volume>(imv9) << std::endl
+                  << imv10 << " = " << quantity<cup_volume>(imv10) << std::endl
+                  << std::endl;
+
+        std::cout << imv1 << " = " << quantity<pint_volume>(imv1) << std::endl
+                  << imv2 << " = " << quantity<pint_volume>(imv2) << std::endl
+                  << imv3 << " = " << quantity<pint_volume>(imv3) << std::endl
+                  << imv4 << " = " << quantity<pint_volume>(imv4) << std::endl
+                  << imv5 << " = " << quantity<pint_volume>(imv5) << std::endl
+                  << imv6 << " = " << quantity<pint_volume>(imv6) << std::endl
+                  << imv7 << " = " << quantity<pint_volume>(imv7) << std::endl
+                  << imv8 << " = " << quantity<pint_volume>(imv8) << std::endl
+                  << imv9 << " = " << quantity<pint_volume>(imv9) << std::endl
+                  << imv10 << " = " << quantity<pint_volume>(imv10) << std::endl
+                  << std::endl;
+
+        std::cout << imv1 << " = " << quantity<quart_volume>(imv1) << std::endl
+                  << imv2 << " = " << quantity<quart_volume>(imv2) << std::endl
+                  << imv3 << " = " << quantity<quart_volume>(imv3) << std::endl
+                  << imv4 << " = " << quantity<quart_volume>(imv4) << std::endl
+                  << imv5 << " = " << quantity<quart_volume>(imv5) << std::endl
+                  << imv6 << " = " << quantity<quart_volume>(imv6) << std::endl
+                  << imv7 << " = " << quantity<quart_volume>(imv7) << std::endl
+                  << imv8 << " = " << quantity<quart_volume>(imv8) << std::endl
+                  << imv9 << " = " << quantity<quart_volume>(imv9) << std::endl
+                  << imv10 << " = " << quantity<quart_volume>(imv10) << std::endl
+                  << std::endl;
+
+        std::cout << imv1 << " = " << quantity<gallon_volume>(imv1) << std::endl
+                  << imv2 << " = " << quantity<gallon_volume>(imv2) << std::endl
+                  << imv3 << " = " << quantity<gallon_volume>(imv3) << std::endl
+                  << imv4 << " = " << quantity<gallon_volume>(imv4) << std::endl
+                  << imv5 << " = " << quantity<gallon_volume>(imv5) << std::endl
+                  << imv6 << " = " << quantity<gallon_volume>(imv6) << std::endl
+                  << imv7 << " = " << quantity<gallon_volume>(imv7) << std::endl
+                  << imv8 << " = " << quantity<gallon_volume>(imv8) << std::endl
+                  << imv9 << " = " << quantity<gallon_volume>(imv9) << std::endl
+                  << imv10 << " = " << quantity<gallon_volume>(imv10) << std::endl
+                  << std::endl;
+    }
+    
+    return 0;
+}
diff --git a/example/temperature.cpp b/example/temperature.cpp
new file mode 100644
index 0000000..f6b4342
--- /dev/null
+++ b/example/temperature.cpp
@@ -0,0 +1,98 @@
+// Boost.Units - A C++ library for zero-overhead dimensional analysis and 
+// unit/quantity manipulation and conversion
+//
+// Copyright (C) 2003-2008 Matthias Christian Schabel
+// Copyright (C) 2008 Steven Watanabe
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+/** 
+\file
+    
+\brief temperature.cpp
+
+\details
+Conversions between Fahrenheit and Kelvin for absolute temperatures and 
+temperature differences.
+
+Output:
+@verbatim
+
+//[ temperature_output_1
+{ 32 } F
+{ 273.15 } K
+{ 273.15 } K
+[ 32 ] F
+[ 17.7778 ] K
+[ 17.7778 ] K
+//]
+
+@endverbatim
+**/
+
+#include <iomanip>
+#include <iostream>
+
+#include <boost/units/absolute.hpp>
+#include <boost/units/get_system.hpp>
+#include <boost/units/io.hpp>
+#include <boost/units/unit.hpp>
+#include <boost/units/quantity.hpp>
+#include <boost/units/systems/si/temperature.hpp>
+#include <boost/units/detail/utility.hpp>
+
+#include <boost/units/base_units/temperature/fahrenheit.hpp>
+
+using namespace boost::units;
+
+namespace boost {
+
+namespace units {
+
+namespace fahrenheit {
+
+//[temperature_snippet_1
+typedef temperature::fahrenheit_base_unit::unit_type    temperature;
+typedef get_system<temperature>::type                   system;
+
+BOOST_UNITS_STATIC_CONSTANT(degree,temperature);
+BOOST_UNITS_STATIC_CONSTANT(degrees,temperature);
+//]
+
+} // fahrenheit
+
+} // namespace units
+
+} // namespace boost
+
+int main()
+{
+    //[temperature_snippet_3
+    quantity<absolute<fahrenheit::temperature> >    T1p(
+        32.0*absolute<fahrenheit::temperature>());
+    quantity<fahrenheit::temperature>               T1v(
+        32.0*fahrenheit::degrees);
+    
+    quantity<absolute<si::temperature> >            T2p(T1p);
+    quantity<si::temperature>                       T2v(T1v);
+    //]
+
+    typedef conversion_helper<
+        quantity<absolute<fahrenheit::temperature> >,
+        quantity<absolute<si::temperature> > >          absolute_conv_type;
+    typedef conversion_helper<
+        quantity<fahrenheit::temperature>,
+        quantity<si::temperature> >                     relative_conv_type;
+    
+    std::cout << T1p << std::endl
+              << absolute_conv_type::convert(T1p) << std::endl
+              << T2p << std::endl
+              << T1v << std::endl
+              << relative_conv_type::convert(T1v) << std::endl
+              << T2v << std::endl
+              << std::endl;
+
+    return 0;
+}
diff --git a/example/test_system.hpp b/example/test_system.hpp
new file mode 100644
index 0000000..0eaaa97
--- /dev/null
+++ b/example/test_system.hpp
@@ -0,0 +1,153 @@
+// Boost.Units - A C++ library for zero-overhead dimensional analysis and 
+// unit/quantity manipulation and conversion
+//
+// Copyright (C) 2003-2008 Matthias Christian Schabel
+// Copyright (C) 2008 Steven Watanabe
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef MCS_TEST_SYSTEM_HPP
+#define MCS_TEST_SYSTEM_HPP
+
+#include <boost/mpl/list.hpp>
+#include <boost/mpl/vector.hpp>
+
+#include <boost/units/base_dimension.hpp>
+#include <boost/units/derived_dimension.hpp>
+#include <boost/units/io.hpp>
+#include <boost/units/quantity.hpp>
+#include <boost/units/static_constant.hpp>
+#include <boost/units/unit.hpp>
+#include <boost/units/base_unit.hpp>
+#include <boost/units/make_system.hpp>
+
+namespace boost {
+
+namespace units {
+
+//[test_system_snippet_1
+
+/// base dimension of length
+struct length_base_dimension : base_dimension<length_base_dimension,1> { };
+/// base dimension of mass
+struct mass_base_dimension : base_dimension<mass_base_dimension,2> { };
+/// base dimension of time
+struct time_base_dimension : base_dimension<time_base_dimension,3> { };
+
+//]
+
+#if 0
+//[test_system_snippet_2
+
+typedef make_dimension_list<
+    boost::mpl::list< dim< length_base_dimension,static_rational<1> > >
+>::type   length_dimension;
+
+typedef make_dimension_list<
+    boost::mpl::list< dim< mass_base_dimension,static_rational<1> > >
+>::type     mass_dimension;
+
+typedef make_dimension_list<
+    boost::mpl::list< dim< time_base_dimension,static_rational<1> > >
+>::type     time_dimension;
+
+//]
+#endif
+
+//[test_system_snippet_3
+typedef length_base_dimension::dimension_type    length_dimension;
+typedef mass_base_dimension::dimension_type      mass_dimension;
+typedef time_base_dimension::dimension_type      time_dimension;
+//]
+
+#if 0
+//[test_system_snippet_4
+
+typedef make_dimension_list<
+    boost::mpl::list< dim< length_base_dimension,static_rational<2> > >
+>::type   area_dimension;
+
+typedef make_dimension_list<
+    boost::mpl::list< dim< mass_base_dimension,static_rational<1> >,
+                      dim< length_base_dimension,static_rational<2> >,
+                      dim< time_base_dimension,static_rational<-2> > >
+>::type    energy_dimension;
+
+//]
+#endif
+
+//[test_system_snippet_5
+typedef derived_dimension<length_base_dimension,2>::type  area_dimension;
+typedef derived_dimension<mass_base_dimension,1,
+                          length_base_dimension,2,
+                          time_base_dimension,-2>::type   energy_dimension;
+//]
+
+namespace test {
+
+//[test_system_snippet_6
+
+struct meter_base_unit : base_unit<meter_base_unit, length_dimension, 1> { };
+struct kilogram_base_unit : base_unit<kilogram_base_unit, mass_dimension, 2> { };
+struct second_base_unit : base_unit<second_base_unit, time_dimension, 3> { };
+
+typedef make_system<
+    meter_base_unit,
+    kilogram_base_unit,
+    second_base_unit>::type mks_system;
+
+/// unit typedefs
+typedef unit<dimensionless_type,mks_system>      dimensionless;
+
+typedef unit<length_dimension,mks_system>        length;
+typedef unit<mass_dimension,mks_system>          mass;
+typedef unit<time_dimension,mks_system>          time;
+
+typedef unit<area_dimension,mks_system>          area;
+typedef unit<energy_dimension,mks_system>        energy;
+//]
+
+//[test_system_snippet_7
+/// unit constants 
+BOOST_UNITS_STATIC_CONSTANT(meter,length);
+BOOST_UNITS_STATIC_CONSTANT(meters,length);
+BOOST_UNITS_STATIC_CONSTANT(kilogram,mass);
+BOOST_UNITS_STATIC_CONSTANT(kilograms,mass);
+BOOST_UNITS_STATIC_CONSTANT(second,time);
+BOOST_UNITS_STATIC_CONSTANT(seconds,time);
+
+BOOST_UNITS_STATIC_CONSTANT(square_meter,area);
+BOOST_UNITS_STATIC_CONSTANT(square_meters,area);
+BOOST_UNITS_STATIC_CONSTANT(joule,energy);
+BOOST_UNITS_STATIC_CONSTANT(joules,energy);
+//]
+
+} // namespace test
+
+//[test_system_snippet_8
+template<> struct base_unit_info<test::meter_base_unit>
+{
+    static std::string name()               { return "meter"; }
+    static std::string symbol()             { return "m"; }
+};
+//]
+
+template<> struct base_unit_info<test::kilogram_base_unit>
+{
+    static std::string name()               { return "kilogram"; }
+    static std::string symbol()             { return "kg"; }
+};
+
+template<> struct base_unit_info<test::second_base_unit>
+{
+    static std::string name()               { return "second"; }
+    static std::string symbol()             { return "s"; }
+};
+
+} // namespace units
+
+} // namespace boost
+
+#endif // MCS_TEST_SYSTEM_HPP
diff --git a/example/tutorial.cpp b/example/tutorial.cpp
new file mode 100644
index 0000000..acda5ee
--- /dev/null
+++ b/example/tutorial.cpp
@@ -0,0 +1,95 @@
+// Boost.Units - A C++ library for zero-overhead dimensional analysis and 
+// unit/quantity manipulation and conversion
+//
+// Copyright (C) 2003-2008 Matthias Christian Schabel
+// Copyright (C) 2008 Steven Watanabe
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+/**
+\file tutorial.cpp
+    
+\brief Basic tutorial using SI units.
+
+\details
+Tutorial 
+Defines a function that computes the work, in joules,
+done by exerting a force in newtons over a specified distance 
+in meters and outputs the result to std::cout. 
+
+Also code for computing the complex impedance
+using std::complex<double> as the value type.
+
+Output:
+@verbatim
+//[tutorial_output
+F  = 2 N
+dx = 2 m
+E  = 4 J
+
+V   = (12.5,0) V
+I   = (3,4) A
+Z   = (1.5,-2) Ohm
+I*Z = (12.5,0) V
+I*Z == V? true
+//]
+@endverbatim
+*/
+
+//[tutorial_code
+#include <complex>
+#include <iostream>
+
+#include <boost/typeof/std/complex.hpp>
+
+#include <boost/units/systems/si/energy.hpp>
+#include <boost/units/systems/si/force.hpp>
+#include <boost/units/systems/si/length.hpp>
+#include <boost/units/systems/si/electric_potential.hpp>
+#include <boost/units/systems/si/current.hpp>
+#include <boost/units/systems/si/resistance.hpp>
+#include <boost/units/systems/si/io.hpp>
+
+using namespace boost::units;
+using namespace boost::units::si;
+
+constexpr
+quantity<energy> 
+work(const quantity<force>& F, const quantity<length>& dx)
+{
+    return F * dx; // Defines the relation: work = force * distance.
+}
+
+int main()
+{   
+    /// Test calculation of work.
+    quantity<force>     F(2.0 * newton); // Define a quantity of force.
+    quantity<length>    dx(2.0 * meter); // and a distance,
+    quantity<energy>    E(work(F,dx));  // and calculate the work done.
+    
+    std::cout << "F  = " << F << std::endl
+              << "dx = " << dx << std::endl
+              << "E  = " << E << std::endl
+              << std::endl;
+
+    /// Test and check complex quantities.
+    typedef std::complex<double> complex_type; // double real and imaginary parts.
+    
+    // Define some complex electrical quantities.
+    quantity<electric_potential, complex_type> v = complex_type(12.5, 0.0) * volts;
+    quantity<current, complex_type>            i = complex_type(3.0, 4.0) * amperes;
+    quantity<resistance, complex_type>         z = complex_type(1.5, -2.0) * ohms;
+    
+    std::cout << "V   = " << v << std::endl
+              << "I   = " << i << std::endl
+              << "Z   = " << z << std::endl 
+              // Calculate from Ohm's law voltage = current * resistance.
+              << "I * Z = " << i * z << std::endl
+              // Check defined V is equal to calculated.
+              << "I * Z == V? " << std::boolalpha << (i * z == v) << std::endl
+              << std::endl;
+    return 0;
+}
+//]
diff --git a/example/unit.cpp b/example/unit.cpp
new file mode 100644
index 0000000..934d557
--- /dev/null
+++ b/example/unit.cpp
@@ -0,0 +1,73 @@
+// Boost.Units - A C++ library for zero-overhead dimensional analysis and 
+// unit/quantity manipulation and conversion
+//
+// Copyright (C) 2003-2008 Matthias Christian Schabel
+// Copyright (C) 2008 Steven Watanabe
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+/** 
+\file
+    
+\brief unit.cpp
+
+\details
+Test unit algebra.
+
+Output:
+@verbatim
+
+//[unit_output
+L             = m
+L+L           = m
+L-L           = m
+L/L           = dimensionless 
+meter*meter   = m^2
+M*(L/T)*(L/T) = m^2 kg s^-2
+M*(L/T)^2     = m^2 kg s^-2
+L^3           = m^3
+L^(3/2)       = m^(3/2)
+2vM           = kg^(1/2)
+(3/2)vM       = kg^(2/3)
+//]
+
+@endverbatim
+**/
+
+#include <iostream>
+
+#include "test_system.hpp"
+
+#include <boost/units/pow.hpp>
+
+int main()
+{
+    using namespace boost::units;
+    using namespace boost::units::test;
+
+    //[unit_snippet_1
+    const length                    L;
+    const mass                      M;
+    // needs to be namespace-qualified because of global time definition
+    const boost::units::test::time  T;
+    const energy                    E;
+    //]
+    
+    std::cout << "L             = " << L << std::endl
+              << "L+L           = " << L+L << std::endl
+              << "L-L           = " << L-L << std::endl
+              << "L/L           = " << L/L << std::endl
+              << "meter*meter   = " << meter*meter << std::endl
+              << "M*(L/T)*(L/T) = " << M*(L/T)*(L/T) << std::endl
+              << "M*(L/T)^2     = " << M*pow<2>(L/T) << std::endl
+              << "L^3           = " << pow<3>(L) << std::endl
+              << "L^(3/2)       = " << pow<static_rational<3,2> >(L)
+              << std::endl
+              << "2vM           = " << root<2>(M) << std::endl
+              << "(3/2)vM       = " << root<static_rational<3,2> >(M)
+              << std::endl;
+
+    return 0;
+}