Squashed 'third_party/boostorg/format/' content from commit a1c6137

Change-Id: I7c2f1d4813c1e733fcf553b4ed9c418e661b0ea8
git-subtree-dir: third_party/boostorg/format
git-subtree-split: a1c613764dd96f97749e1e059c80f0f3515fcf0b
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..e872b7c
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,162 @@
+# Copyright 2016 Peter Dimov
+# Copyright 2017, 2018 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)
+
+#
+# Generic Travis CI build script for boostorg repositories
+#
+# Instructions for customizing this script for your library:
+# 
+# 1. Customize the compilers and language levels you want.
+# 2. If you have move than include/, src/, test/, example/, examples/, or
+#    tools/ directories, modify your Travis CI project and add the environment
+#    variable DEPINST.  For example if your build uses code in "bench/" and
+#    "fog/" directories, then set DEPINST to the following:
+#        --include bench --include fog
+# 3. If you want to enable Coverity Scan, you need to provide the environment
+#    variables COVERITY_SCAN_TOKEN and COVERITY_SCAN_NOTIFICATION_EMAIL in
+#    your github settings.
+# 4. Enable pull request builds in your boostorg/<library> account.
+# 5. Change the default C++ version in ci/travis/*.sh (search for CXXSTD) if needed.
+#
+# That's it - the scripts will do everything else for you.
+
+sudo: false
+dist: trusty
+language: cpp
+
+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:
+  - git clone https://github.com/jeking3/boost-ci.git boost-ci
+  - cp -pr boost-ci/ci boost-ci/.codecov.yml .
+  - source ci/travis/install.sh
+
+addons:
+  apt:
+    packages:
+      - binutils-gold
+      - gdb
+      - libc6-dbg
+        
+branches:
+  only:
+    - develop
+    - master
+    
+script:
+  - cd $BOOST_ROOT/libs/$SELF
+  - ci/travis/build.sh
+
+jobs:
+  include:
+    #################### Jobs to run on every pull request ####################
+    - os: linux
+      env: 
+        - COMMENT="C++03"
+        - TOOLSET=gcc,gcc-7,clang
+      addons:
+        apt:
+          packages:
+            - g++-7
+          sources:
+            - ubuntu-toolchain-r-test
+    - os: linux
+      env: 
+        - COMMENT="C++11"
+        - TOOLSET=gcc,gcc-7,clang
+        - CXXSTD=11
+      addons:
+        apt:
+          packages:
+            - g++-7
+          sources:
+            - ubuntu-toolchain-r-test
+    - os: linux
+      env: 
+        - COMMENT=valgrind
+        - TOOLSET=clang 
+        - B2_VARIANT=variant=debug
+        - TESTFLAGS=testing.launcher=valgrind
+        - VALGRIND_OPTS=--error-exitcode=1
+      addons:
+        apt:
+          packages:
+            - clang-5.0
+            - libstdc++-7-dev
+            - valgrind
+          sources:
+            - llvm-toolchain-trusty-5.0
+            - ubuntu-toolchain-r-test
+
+    - os: linux
+      env:
+        - COMMENT=cppcheck
+      script:
+        - cd $BOOST_ROOT/libs/$SELF
+        - ci/travis/cppcheck.sh
+
+    - os: linux
+      env:
+        - COMMENT=UBSAN
+        - B2_VARIANT=variant=debug
+        - TOOLSET=gcc-7
+        - CXXFLAGS="cxxflags=-fno-omit-frame-pointer cxxflags=-fsanitize=undefined cxxflags=-fno-sanitize-recover=undefined"
+        - LINKFLAGS="linkflags=-fsanitize=undefined linkflags=-fno-sanitize-recover=undefined linkflags=-fuse-ld=gold"
+        - UBSAN_OPTIONS=print_stacktrace=1
+      addons:
+        apt:
+          packages:
+            - g++-7
+          sources:
+            - ubuntu-toolchain-r-test
+
+    - os: linux
+      env: 
+        - COMMENT=CodeCov
+        - TOOLSET=gcc-7
+      addons:
+        apt:
+          packages:
+            - gcc-7
+            - g++-7
+          sources:
+            - ubuntu-toolchain-r-test
+      script:
+        - pushd /tmp && git clone https://github.com/linux-test-project/lcov.git && export PATH=/tmp/lcov/bin:$PATH && which lcov && lcov --version && popd
+        - cd $BOOST_ROOT/libs/$SELF
+        - ci/travis/codecov.sh
+
+  # does not work with sourced install shell yet: see 
+  # https://travis-ci.org/jeking3/tokenizer/jobs/384903189
+  # for a typical failure
+  # - os: osx
+  #   osx_image: xcode9
+  #   env:
+  #     - TOOLSET=clang
+  #     - CXXSTD=03,11
+
+    #################### Jobs to run on pushes to master, develop ###################
+
+    # Coverity Scan
+    - os: linux
+      if: (env(COVERITY_SCAN_NOTIFICATION_EMAIL) IS present) AND (branch IN (develop, master)) AND (type IN (cron, push))
+      env:
+        - COMMENT="Coverity Scan"
+        - TOOLSET=gcc
+      script:
+        - cd $BOOST_ROOT/libs/$SELF
+        - ci/travis/coverity.sh
+
+notifications:
+  email:
+    false
+
diff --git a/Jamfile b/Jamfile
new file mode 100644
index 0000000..5f53e9b
--- /dev/null
+++ b/Jamfile
@@ -0,0 +1,27 @@
+#  Boost.Format Library Jamfile
+#
+#  Copyright (c) 2003 Samuel Krempp
+#
+#  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)
+
+project
+    : requirements
+
+      <warnings>all
+
+      <toolset>clang:<cxxflags>-Wextra
+      <toolset>clang:<cxxflags>-ansi
+      <toolset>clang:<cxxflags>-pedantic
+
+      <toolset>gcc:<cxxflags>-Wextra
+      <toolset>gcc:<cxxflags>-ansi
+      <toolset>gcc:<cxxflags>-pedantic
+    ;
+
+# please order by name to ease maintenance
+build-project benchmark ;
+build-project example ;
+build-project test ;
+build-project tools ;
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..36b7cd9
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,23 @@
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..25c0b15
--- /dev/null
+++ b/README.md
@@ -0,0 +1,36 @@
+Format, part of the collection of [Boost C++ Libraries](http://github.com/boostorg), provides a type-safe mechanism for formatting arguments according to a printf-like format-string.  User-defined types are supported by providing a `std::ostream operator <<` implementation for them.
+
+### License
+
+Distributed under the [Boost Software License, Version 1.0](http://www.boost.org/LICENSE_1_0.txt).
+
+### Properties
+
+* C++03
+* Header-only
+
+### Build Status
+
+Branch          | Travis | Appveyor | Coverity Scan | codecov.io | Deps | Docs | Tests |
+:-------------: | ------ | -------- | ------------- | ---------- | ---- | ---- | ----- |
+[`master`](https://github.com/boostorg/format/tree/master) | [![Build Status](https://travis-ci.org/boostorg/format.svg?branch=master)](https://travis-ci.org/boostorg/format) | [![Build status](https://ci.appveyor.com/api/projects/status/tkcumf8nu6tb697d/branch/master?svg=true)](https://ci.appveyor.com/project/jeking3/format-bhjc4/branch/master) | [![Coverity Scan Build Status](https://scan.coverity.com/projects/14007/badge.svg)](https://scan.coverity.com/projects/boostorg-format) | [![codecov](https://codecov.io/gh/boostorg/format/branch/master/graph/badge.svg)](https://codecov.io/gh/boostorg/format/branch/master) | [![Deps](https://img.shields.io/badge/deps-master-brightgreen.svg)](https://pdimov.github.io/boostdep-report/master/format.html) | [![Documentation](https://img.shields.io/badge/docs-master-brightgreen.svg)](http://www.boost.org/doc/libs/master/doc/html/format.html) | [![Enter the Matrix](https://img.shields.io/badge/matrix-master-brightgreen.svg)](http://www.boost.org/development/tests/master/developer/format.html)
+[`develop`](https://github.com/boostorg/format/tree/develop) | [![Build Status](https://travis-ci.org/boostorg/format.svg?branch=develop)](https://travis-ci.org/boostorg/format) | [![Build status](https://ci.appveyor.com/api/projects/status/tkcumf8nu6tb697d/branch/develop?svg=true)](https://ci.appveyor.com/project/jeking3/format-bhjc4/branch/develop) | [![Coverity Scan Build Status](https://scan.coverity.com/projects/14007/badge.svg)](https://scan.coverity.com/projects/boostorg-format) | [![codecov](https://codecov.io/gh/boostorg/format/branch/develop/graph/badge.svg)](https://codecov.io/gh/boostorg/format/branch/develop) | [![Deps](https://img.shields.io/badge/deps-develop-brightgreen.svg)](https://pdimov.github.io/boostdep-report/develop/format.html) | [![Documentation](https://img.shields.io/badge/docs-develop-brightgreen.svg)](http://www.boost.org/doc/libs/develop/doc/html/format.html) | [![Enter the Matrix](https://img.shields.io/badge/matrix-develop-brightgreen.svg)](http://www.boost.org/development/tests/develop/developer/format.html)
+
+### Directories
+
+| Name        | Purpose                        |
+| ----------- | ------------------------------ |
+| `benchmark` | benchmark tool                 |
+| `doc`       | documentation                  |
+| `examples`  | use case examples              |
+| `include`   | headers                        |
+| `test`      | unit tests                     |
+| `tools`     | development tools              |
+
+### More information
+
+* [Ask questions](http://stackoverflow.com/questions/ask?tags=c%2B%2B,boost,boost-format): Be sure to read the documentation first as Boost.Format, like any other string formatting library, has its own rules.
+* [Report bugs](https://github.com/boostorg/format/issues): Be sure to mention Boost version, platform and compiler you're using. A small compilable code sample to reproduce the problem is always good as well.
+* [Submit Pull Requests](https://github.com/boostorg/format/pulls) against the **develop** branch. Note that by submitting patches you agree to license your modifications under the [Boost Software License, Version 1.0](http://www.boost.org/LICENSE_1_0.txt).  Be sure to include tests proving your changes work properly.
+* Discussions about the library are held on the [Boost developers mailing list](http://www.boost.org/community/groups.html#main). Be sure to read the [discussion policy](http://www.boost.org/community/policy.html) before posting and add the `[format]` tag at the beginning of the subject line.
+
diff --git a/appveyor.yml b/appveyor.yml
new file mode 100644
index 0000000..144a178
--- /dev/null
+++ b/appveyor.yml
@@ -0,0 +1,81 @@
+# Copyright 2016, 2017 Peter Dimov
+# Copyright (C) 2017, 2018 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)
+
+version: 1.0.{build}-{branch}
+
+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
+    CXXSTD: 03
+
+  matrix:
+    - FLAVOR: Visual Studio 2017
+      APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
+      TOOLSET: msvc-14.1
+      B2_ADDRESS_MODEL: address-model=64,32
+    - FLAVOR: Visual Studio 2015
+      APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
+      TOOLSET: msvc-14.0
+      B2_ADDRESS_MODEL: address-model=64,32
+    - FLAVOR: Visual Studio 2010, 2012, 2013
+      APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013
+      TOOLSET: msvc-10.0,msvc-11.0,msvc-12.0
+    - FLAVOR: cygwin (32-bit)
+      APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
+      ADDPATH: C:\cygwin\bin;
+      B2_ADDRESS_MODEL: address-model=32
+      # https://github.com/boostorg/test/issues/144
+      DEFINES: define=_POSIX_C_SOURCE=200112L
+      THREADING: threadapi=pthread
+      TOOLSET: gcc
+    - FLAVOR: cygwin (64-bit)
+      APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
+      ADDPATH: C:\cygwin64\bin;
+      B2_ADDRESS_MODEL: address-model=64
+      # https://github.com/boostorg/test/issues/144
+      DEFINES: define=_POSIX_C_SOURCE=200112L
+      THREADING: threadapi=pthread
+      TOOLSET: gcc
+    - FLAVOR:  mingw32
+      APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
+      ARCH:    i686
+      B2_ADDRESS_MODEL: address-model=32
+      SCRIPT:  ci\appveyor\mingw.bat
+    - FLAVOR:  mingw64
+      APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
+      ARCH:    x86_64
+      B2_ADDRESS_MODEL: address-model=64
+      SCRIPT:  ci\appveyor\mingw.bat
+
+install:
+  - set SELF=%APPVEYOR_PROJECT_NAME:-=_%
+  - git clone https://github.com/jeking3/boost-ci.git C:\boost-ci
+  - xcopy /s /e /q /i C:\boost-ci\ci .\ci
+  - ci\appveyor\install.bat
+
+build: off
+
+test_script:
+  - set SELF=%APPVEYOR_PROJECT_NAME:-=_%
+  - PATH=%ADDPATH%%PATH%
+  - IF DEFINED SCRIPT (call libs\%SELF%\%SCRIPT%) ELSE (b2 libs/%SELF% toolset=%TOOLSET% cxxstd=%CXXSTD% %CXXFLAGS% %DEFINES% %THREADING% %B2_ADDRESS_MODEL% %B2_LINK% %B2_THREADING% %B2_VARIANT% -j3)
+
diff --git a/benchmark/Jamfile b/benchmark/Jamfile
new file mode 100644
index 0000000..0a420ab
--- /dev/null
+++ b/benchmark/Jamfile
@@ -0,0 +1,27 @@
+#  Boost.Format Library benchmark Jamfile
+#
+#  Copyright (c) 2003 Samuel Krempp
+#
+#  Distributed under the Boost Software License, Version 1.0.
+#  See www.boost.org/LICENSE_1_0.txt
+#
+
+project libs/format/benchmark 
+    : requirements
+	  <toolset>msvc:<define>_CRT_SECURE_NO_WARNINGS
+	;
+
+exe bench_format_no_locale
+    : bench_format.cpp
+    : <define>BOOST_NO_STD_LOCALE <location-prefix>no_locale    
+    ;
+
+exe bench_format_normal
+    : bench_format.cpp 
+    : <location-prefix>normal
+    ;
+
+exe bench_format_no_reuse_stream
+    : bench_format.cpp
+    : <include>alts <define>BOOST_FORMAT_NO_OSS_MEMBER <location-prefix>no_reuse_stream
+    ;
diff --git a/benchmark/bench_format.cpp b/benchmark/bench_format.cpp
new file mode 100644
index 0000000..393df75
--- /dev/null
+++ b/benchmark/bench_format.cpp
@@ -0,0 +1,356 @@
+// -*- C++ -*-
+//  Boost general library 'format'  ---------------------------
+//  See http://www.boost.org for updates, documentation, and revision history.
+
+//  Copyright (c) 2001 Samuel Krempp
+//                  krempp@crans.ens-cachan.fr
+//  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)
+
+// several suggestions from Jens Maurer
+
+// ------------------------------------------------------------------------------
+// bench_variants.cc :  do the same task, with sprintf, stream, and format
+//                      and compare their times.
+
+// This benchmark is provided purely for information.
+// It might not even compile as-is, 
+//   or not give any sensible results. 
+//      (e.g., it expects sprintf to be POSIX compliant)
+
+// ------------------------------------------------------------------------------
+
+
+#include <iostream>
+#include <iomanip>
+#include <cstdio>  // sprintf
+#include <cstring>
+#include <fstream>
+#include <cmath>   // floor
+#include <boost/timer.hpp>
+#include <vector>
+
+#include <boost/format.hpp>
+
+// portable /dev/null stream equivalent, by James Kanze, http://www.gabi-soft.de
+class NulStreambuf : public std::streambuf
+{
+public:
+  NulStreambuf() { 
+      setp( dummyBuffer , dummyBuffer + 64 ) ;
+  }
+  virtual int  overflow( int c );
+  virtual int  underflow(); 
+private:
+    char                dummyBuffer[ 64 ] ;
+} ;
+
+class NulStream : public std::basic_ostream<char, std::char_traits<char> > 
+{
+public:
+  NulStream();
+  virtual ~NulStream();
+  NulStreambuf*    rdbuf() {
+    return static_cast< NulStreambuf* >(
+                   ((std::basic_ostream<char, std::char_traits<char> > *) this) -> rdbuf() ) ;
+  }
+} ;
+ 
+
+//-------------------------------------------------------------------------------------
+//   NulStream implementation
+
+NulStream::NulStream()  : std::basic_ostream<char, std::char_traits<char> > (NULL) {
+  init( new NulStreambuf ) ;
+}
+
+NulStream::~NulStream() {
+    delete rdbuf() ;
+}
+
+int  NulStreambuf::underflow(){ return std::ios::traits_type::eof();    
+}
+
+int NulStreambuf::overflow( int c ){
+    setp( dummyBuffer , dummyBuffer + 64 ) ;
+    return (c == std::ios::traits_type::eof()) ? '\0' : c ;
+}
+
+
+
+// -------------------------------------------------------------------------------------
+
+namespace benchmark {
+
+static int NTests = 300000;
+
+//static std::stringstream nullStream;
+static NulStream nullStream;
+static double tstream, tpf;
+//static const std::string fstring="%3$#x %1$20.10E %2$g %3$d \n";
+static const std::string fstring="%3$0#6x %1$20.10E %2$g %3$0+5d \n";
+static const double     arg1=45.23;
+static const double     arg2=12.34;
+static const int        arg3=23;
+static const std::string res = 
+"0x0017     4.5230000000E+01 12.34 +0023 \n";
+//static const std::string res = "23.0000     4.5230000000E+01 12.34 23 \n";
+
+void test_sprintf();
+void test_nullstream();
+void test_opti_nullstream();
+void test_parsed_once_format();
+void test_reused_format();
+void test_format();
+void test_try1();
+void test_try2();
+
+void test_sprintf()
+{
+    using namespace std;
+
+    vector<char> bufr;
+    bufr.reserve(4000);
+    char *buf = &bufr[0];
+
+    // Check that sprintf is Unix98 compatible on the platform :
+    sprintf(buf, fstring.c_str(), arg1, arg2, arg3);
+    if( strncmp( buf, res.c_str(), res.size()) != 0 ) {
+      cerr << endl << buf;
+    }
+    // time the loop :
+    boost::timer chrono;
+    for(int i=0; i<NTests; ++i) {
+      sprintf(buf, fstring.c_str(), arg1, arg2, arg3);
+    }
+    tpf=chrono.elapsed();
+    cout  << left << setw(20) <<"printf time"<< right <<":" << tpf  << endl;
+}
+
+void test_try1()
+{
+  using namespace std;
+  boost::io::basic_oaltstringstream<char> oss;
+  oss << boost::format(fstring) % arg1 % arg2 % arg3;
+  boost::timer chrono;
+  size_t dummy=0;
+  for(int i=0; i<NTests; ++i) {
+      dummy += oss.cur_size();
+  }
+  double t = chrono.elapsed();
+  cout  << left << setw(20) <<"try1 time"<< right <<":" << setw(5) << t
+        << ",  = " << t / tpf << " * printf "
+        << ",  = " << t / tstream << " * nullStream \n";
+}
+
+void test_try2()
+{
+  using namespace std;
+  boost::io::basic_oaltstringstream<char> oss;
+  oss << boost::format(fstring) % arg1 % arg2 % arg3;
+  oss << "blas 34567890GGGGGGGGGGGGGGGGGGGGGGGGGGGGggggggggggggggggggggggggggg " << endl;
+  string s = oss.cur_str();
+  oss << s << s << s;
+  oss.clear_buffer();
+  oss << s << s;
+  s = oss.cur_str();
+  boost::timer chrono;
+  size_t dummy=0;
+  for(int i=0; i<NTests; ++i) {
+      dummy += oss.cur_size();
+  }
+  double t = chrono.elapsed();
+  cout  << left << setw(20) <<"try2 time"<< right <<":" << setw(5) << t
+        << ",  = " << t / tpf << " * printf "
+        << ",  = " << t / tstream << " * nullStream \n";
+}
+
+void do_stream(std::ostream& os) {
+    using namespace std;
+    std::ios_base::fmtflags f = os.flags();
+    os << hex << showbase << internal << setfill('0') << setw(6) << arg3
+       << dec << noshowbase << right << setfill(' ') 
+       << " " 
+       << scientific << setw(20) << setprecision(10) << uppercase << arg1 
+       << setprecision(6) << nouppercase ;
+    os.flags(f);
+    os << " " << arg2 << " " 
+       << showpos << setw(5) << internal << setfill('0') << arg3 << " \n" ;
+    os.flags(f);
+}
+
+void test_nullstream()
+{
+    using namespace std;
+    boost::timer chrono;
+    boost::io::basic_oaltstringstream<char> oss;
+
+    {   
+        do_stream(oss);
+        if(oss.str() != res ) {
+            cerr << endl << oss.str() ;
+        }
+    }
+
+    for(int i=0; i<NTests; ++i) { 
+        do_stream(nullStream);
+    }
+
+//     for(int i=0; i<NTests; ++i) { 
+//       std::ios_base::fmtflags f0 = nullStream.flags();
+//       nullStream << hex << showbase << arg3
+//                  << dec << noshowbase << " " 
+//                  << scientific << setw(20) << setprecision(10) << uppercase <<  arg1 
+//                  << setprecision(0);
+//       nullStream.flags(f0);
+//       nullStream << " " << arg2 << " " << arg3 << " \n" ;
+
+//     }
+    double t = chrono.elapsed();
+    cout  << left << setw(20) <<"ostream time"<< right <<":" << setw(5) << t  
+          << ",  = " << t / tpf << " * printf \n";
+    tstream = t;
+}
+
+void test_opti_nullstream()
+{
+    using namespace std;
+    boost::timer chrono;
+    boost::io::basic_oaltstringstream<char> oss;
+    //static const std::string fstring="%3$#x %1$20.10E %2$g %3$d \n";
+
+    std::ios_base::fmtflags f0 = oss.flags(), f1, f2;
+    streamsize p0 = oss.precision();
+    {
+      oss << hex << showbase; 
+      f1 = oss.flags();
+      oss << arg3;
+
+      oss.flags(f0);
+      oss << " " << scientific << setw(20) << setprecision(10) << uppercase;
+      f2 = oss.flags();
+      oss << arg1;
+
+      oss.flags(f0); oss.precision(p0);
+      oss << " " << arg2 << " " << arg3 << " \n" ;
+    
+      if(oss.str() != res ) {
+        cerr << endl << oss.str() ;
+      }
+    }
+
+    for(int i=0; i<NTests; ++i) { 
+      nullStream.flags(f1);
+      nullStream << arg3;
+
+      nullStream << setw(20) << setprecision(10);
+      nullStream.flags(f2);
+      nullStream << arg1;
+
+      nullStream.flags(f0); nullStream.precision(p0);
+      nullStream << " " << arg2 << " " << arg3 << " \n" ;
+    }
+    double t = chrono.elapsed();
+    cout  << left << setw(20) <<"opti-stream time"<< right <<":" << setw(5) << t  
+          << ",  = " << t / tpf << " * printf \n";
+    //    tstream = t;
+}
+
+void test_parsed_once_format()
+{
+    using namespace std;
+    static const boost::format fmter(fstring);
+
+    boost::io::basic_oaltstringstream<char> oss;
+    oss << boost::format(fmter) % arg1 % arg2 % arg3 ;
+    if( oss.str() != res ) {
+      cerr << endl << oss.str();
+    }
+
+    // not only is the format-string parsed once,
+    // but also the buffer of the internal stringstream is already allocated.
+
+    boost::timer chrono;        
+    for(int i=0; i<NTests; ++i) {
+        nullStream << boost::format(fmter) % arg1 % arg2 % arg3;
+    }
+    double t=chrono.elapsed();
+    cout  << left << setw(20) <<"parsed-once time"<< right <<":" << setw(5) << t 
+          << ",  = " << t / tpf << " * printf "
+          << ",  = " << t / tstream << " * nullStream \n";
+}
+
+void test_reused_format()
+{
+  using namespace std;
+  boost::io::basic_oaltstringstream<char> oss;
+  oss << boost::format(fstring) % arg1 % arg2 % arg3;
+  if(oss.str() != res ) {
+    cerr << endl << oss.str();
+  }
+
+  boost::timer chrono;
+  boost::format fmter;
+  for(int i=0; i<NTests; ++i) {
+    nullStream << fmter.parse(fstring) % arg1 % arg2 % arg3;
+  }
+  double t = chrono.elapsed();
+  cout  << left << setw(20) <<"reused format time"<< right <<":" << setw(5) << t
+        << ",  = " << t / tpf << " * printf "
+        << ",  = " << t / tstream << " * nullStream \n";
+}
+
+void test_format()
+{
+  using namespace std;
+  boost::io::basic_oaltstringstream<char> oss;
+  oss << boost::format(fstring) % arg1 % arg2 % arg3;
+  if(oss.str() != res ) {
+    cerr << endl << oss.str();
+  }
+
+  boost::timer chrono;
+  for(int i=0; i<NTests; ++i) {
+    nullStream << boost::format(fstring) % arg1 % arg2 % arg3;
+  }
+  double t = chrono.elapsed();
+  cout  << left << setw(20) <<"format time"<< right <<":" << setw(5) << t
+        << ",  = " << t / tpf << " * printf "
+        << ",  = " << t / tstream << " * nullStream \n";
+}
+
+} // benchmark
+
+int main(int argc, char * argv[]) {
+    using namespace benchmark;
+    using namespace boost;
+    using namespace std;
+    const string::size_type  npos = string::npos;
+
+    string choices = "";
+    if (1<argc) {
+        choices = (argv[1]); // profiling is easier launching only one.
+        NTests = 1000 * 1000;  // andmoreprecise with many iterations
+        cout << "choices (" << choices << ") \n";
+    }
+
+    if (choices == "" || choices.find('p') != npos)
+        test_sprintf();
+    if (choices == "" || choices.find('n') != npos)
+        test_nullstream();
+    if (choices == "" || choices.find('1') != npos)
+        test_parsed_once_format();
+    if (choices == "" || choices.find('r') != npos)
+        test_reused_format();
+    if (choices == "" || choices.find('f') != npos)
+        test_format();
+    if (choices.find('t') != npos)
+        test_try1();
+    if (choices.find('y') != npos)
+        test_try2();
+    if (choices.find('o') != npos)
+        test_opti_nullstream();
+    return 0;
+}
+
diff --git a/benchmark/results.txt b/benchmark/results.txt
new file mode 100644
index 0000000..4a884de
--- /dev/null
+++ b/benchmark/results.txt
@@ -0,0 +1,293 @@
+// Copyright (c) 2001 Samuel Krempp
+//                  krempp@crans.ens-cachan.fr
+// 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)
+
+// This benchmark is provided purely for information.
+// It might not even compile as-is, 
+//   or not give any sensible results. 
+//      (e.g., it expects sprintf to be POSIX compliant)
+
+ new results ( with  outsstream vs. stringstream)
+
+bjam -sTOOLS="gcc intel-linux-7.1" -sBUILD="release"
+
+( -sBUILD="profile"  for profiling..)
+
+
+ "_no_reuse_stream" "_stringstr" "_strstream" _no_locale 
+
+intel-linux-7.1
+
+for comp in gcc  ; do 
+   echo  "\n------------------- Compiler  $comp : ---------------- "
+   for var in _overloads _basicfmt _normal; do 
+     echo "\n-- Variant  **" $var "**" :
+      texe=$EXEBOOST/libs/format/benchmark/bench_format${var}/${comp}/release/bench_format${var} ;
+      ls -l $texe;
+      $texe
+   done
+done
+
+
+// stringstream recréé chaque fois.
+-- Variant  ** _normal ** :
+-rwx--x--x    1 sam      users       61952 Sep 17 03:13 /home/data/zStore/BBoost/bin/boost//libs/format/benchmark/bench_format_normal/gcc/release/bench_format_normal
+printf time         :2.16
+ostream time        : 3.69,  = 1.70833 * printf
+parsed-once time    : 8.45,  = 3.91204 * printf ,  = 2.28997 * nullStream
+reused format time  :10.94,  = 5.06481 * printf ,  = 2.96477 * nullStream
+format time         :10.97,  = 5.0787 * printf ,  = 2.9729 * nullStream
+
+
+Pour le parsing. step 1 : scan_not + str2int (version Iter const& qques % mieux)
+
+------------------- Compiler  gcc : ----------------
+
+-- Variant  ** _overloads ** :
+-rwx--x--x    1 sam      users       52864 2003-09-12 02:59 /home/sam/progs/Boost/bin/BBoost//libs/format/benchmark/bench_format_overloads/gcc/release/bench_format_overloads
+printf time         :2.21
+ostream time        : 3.57,  = 1.61538 * printf
+parsed-once time    : 4.93,  = 2.23077 * printf ,  = 1.38095 * nullStream
+reused format time  : 9.25,  = 4.18552 * printf ,  = 2.59104 * nullStream
+format time         :10.33,  = 4.67421 * printf ,  = 2.89356 * nullStream
+
+-- Variant  ** _basicfmt ** :
+-rwx--x--x    1 sam      users       52864 2003-09-12 03:00 /home/sam/progs/Boost/bin/BBoost//libs/format/benchmark/bench_format_basicfmt/gcc/release/bench_format_basicfmt
+printf time         :2.2
+ostream time        : 3.57,  = 1.62273 * printf
+parsed-once time    : 4.85,  = 2.20455 * printf ,  = 1.35854 * nullStream
+reused format time  : 9.25,  = 4.20455 * printf ,  = 2.59104 * nullStream
+format time         :10.29,  = 4.67727 * printf ,  = 2.88235 * nullStream
+
+-- Variant  ** _normal ** :
+-rwx--x--x    1 sam      users       53088 2003-09-12 03:00 /home/sam/progs/Boost/bin/BBoost//libs/format/benchmark/bench_format_normal/gcc/release/bench_format_normal
+printf time         :2.27
+ostream time        : 3.47,  = 1.52863 * printf
+parsed-once time    : 4.79,  = 2.11013 * printf ,  = 1.3804 * nullStream
+reused format time  : 9.88,  = 4.35242 * printf ,  = 2.84726 * nullStream
+format time         :10.97,  = 4.8326 * printf ,  = 3.16138 * nullStream
+
+-------------------------------------------------------------------------------------------------
+Overload : int, double char * -> put_simple :
+#if defined(BOOST_FORMAT_OVERLOADS)
+        template<class T>  
+        basic_format&   operator%(const char* x) 
+            { return io::detail::feed_overloaded(*this,x); }
+        template<class T>  
+        basic_format&   operator%(const double x)
+            { return io::detail::feed_overloaded(*this,x); }
+        template<class T>  
+        basic_format&   operator%(const int x)
+            { return io::detail::feed_overloaded(*this,x); }
+#endif
+
+    // put overloads for common types (-> faster)
+    template< class Ch, class Tr, class T> 
+    void put_simple( T x, 
+                     const format_item<Ch, Tr>& specs, 
+                     std::basic_string<Ch, Tr> & res, 
+                     io::basic_outsstream<Ch, Tr>& oss_ )
+    {
+        typedef std::basic_string<Ch, Tr> string_t;
+        typedef format_item<Ch, Tr>  format_item_t;
+    
+        specs.fmtstate_.apply_on(oss_);
+        const std::ios_base::fmtflags fl=oss_.flags();
+        const std::streamsize w = oss_.width();
+      
+        if(w!=0) 
+            oss_.width(0);
+        put_last( oss_, x);
+        const Ch * res_beg = oss_.begin();
+        std::streamsize res_size = std::min(specs.truncate_, oss_.pcount());
+        int prefix_space = 0;
+        if(specs.pad_scheme_ & format_item_t::spacepad)
+            if( res_size == 0 ||   ( res_beg[0] !='+' && res_beg[0] !='-'  ))
+                prefix_space = 1;
+        mk_str(res, res_beg, res_size, w, oss_.fill(), fl, 
+               prefix_space, (specs.pad_scheme_ & format_item_t::centered) !=0 );
+        clear_buffer( oss_);
+    } // end- put_simple(..)
+
+
+
+------------------- Compiler  gcc : ----------------
+
+-- Variant  ** _overloads ** :
+-rwx--x--x    1 sam      users       52832 2003-09-12 00:17 /home/sam/progs/Boost/bin/BBoost//libs/format/benchmark/bench_format_overloads/gcc/release/bench_format_overloads
+printf time         :2.13
+ostream time        : 2.91,  = 1.3662 * printf
+parsed-once time    : 4.48,  = 2.10329 * printf ,  = 1.53952 * nullStream
+reused format time  : 9.42,  = 4.42254 * printf ,  = 3.23711 * nullStream
+format time         : 11.1,  = 5.21127 * printf ,  = 3.81443 * nullStream
+
+RERUN 
+printf time         :2.09
+ostream time        : 2.92,  = 1.39713 * printf
+parsed-once time    : 4.43,  = 2.11962 * printf ,  = 1.51712 * nullStream
+reused format time  : 9.29,  = 4.44498 * printf ,  = 3.18151 * nullStream
+format time         :11.05,  = 5.28708 * printf ,  = 3.78425 * nullStream
+
+-- Variant  ** _basicfmt ** :
+-rwx--x--x    1 sam      users       52832 2003-09-12 00:17 /home/sam/progs/Boost/bin/BBoost//libs/format/benchmark/bench_format_basicfmt/gcc/release/bench_format_basicfmt
+printf time         :2.16
+ostream time        : 3.01,  = 1.39352 * printf
+parsed-once time    : 4.41,  = 2.04167 * printf ,  = 1.46512 * nullStream
+reused format time  : 9.61,  = 4.44907 * printf ,  = 3.19269 * nullStream
+format time         :11.02,  = 5.10185 * printf ,  = 3.66113 * nullStream
+
+-- Variant  ** _no_locale ** :
+-rwx--x--x    1 sam      users       52192 2003-09-12 00:09 /home/sam/progs/Boost/bin/BBoost//libs/format/benchmark/bench_format_no_locale/gcc/release/bench_format_no_locale
+printf time         :2.1
+ostream time        : 2.87,  = 1.36667 * printf
+parsed-once time    : 4.44,  = 2.11429 * printf ,  = 1.54704 * nullStream
+reused format time  : 8.21,  = 3.90952 * printf ,  = 2.86063 * nullStream
+format time         : 9.25,  = 4.40476 * printf ,  = 3.223 * nullStream
+
+-- Variant  ** _normal ** :
+-rwx--x--x    1 sam      users       53056 2003-09-12 00:17 /home/sam/progs/Boost/bin/BBoost//libs/format/benchmark/bench_format_normal/gcc/release/bench_format_normal
+printf time         :2.18
+ostream time        : 2.92,  = 1.33945 * printf
+parsed-once time    : 5.75,  = 2.63761 * printf ,  = 1.96918 * nullStream
+reused format time  :10.27,  = 4.71101 * printf ,  = 3.51712 * nullStream
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+------------------- Compiler  gcc : ----------------
+
+-- Variant  ** _normal ** :
+-rwx--x--x    1 sam      users       49280 2003-09-10 21:12 /home/sam/progs/Boost/bin/BBoost//libs/format/benchmark/bench_format_normal/gcc/release/bench_format_normal
+printf time         :2.16
+ostream time        : 2.81,  = 1.30093 * printf
+stored format time  :11.56,  = 5.35185 * printf ,  = 4.11388 * nullStream
+format time         :18.69,  = 8.65278 * printf ,  = 6.65125 * nullStream
+
+-- Variant  ** _static_stream ** :
+-rwx--x--x    1 sam      users       45856 2003-09-10 21:13 /home/sam/progs/Boost/bin/BBoost//libs/format/benchmark/bench_format_static_stream/gcc/release/bench_format_static_stream
+printf time         :2.1
+ostream time        : 2.79,  = 1.32857 * printf
+stored format time  :  4.5,  = 2.14286 * printf ,  = 1.6129 * nullStream
+format time         :10.05,  = 4.78571 * printf ,  = 3.60215 * nullStream
+
+-- Variant  ** _basicfmt ** :
+-rwx--x--x    1 sam      users       47200 2003-09-10 21:13 /home/sam/progs/Boost/bin/BBoost//libs/format/benchmark/bench_format_basicfmt/gcc/release/bench_format_basicfmt
+printf time         :2.22
+ostream time        : 2.88,  = 1.2973 * printf
+stored format time  : 4.45,  = 2.0045 * printf ,  = 1.54514 * nullStream
+format time         :11.67,  = 5.25676 * printf ,  = 4.05208 * nullStream
+
+
+
+
+
+The cost of imbuing locale after each object is fed :
+
+------------------- Compiler  gcc : ----------------
+-- Variant  _normal :
+-rwx--x--x    1 sam      users       49920 2003-09-10 20:23 /home/sam/progs/Boost/bin/BBoost//libs/format/benchmark/bench_format_normal/gcc/release/bench_format_normal
+printf time         :2.21
+ostream time        :  3.1,  = 1.40271 * printf
+stored format time  :11.53,  = 3.71935 * stream
+format time         :18.86,  = 6.08387 * stream
+
+-- Variant  _static_stream :
+-rwx--x--x    1 sam      users       43232 2003-09-10 20:24 /home/sam/progs/Boost/bin/BBoost//libs/format/benchmark/bench_format_static_stream/gcc/release/bench_format_static_stream
+printf time         :2.19
+ostream time        : 3.09,  = 1.41096 * printf
+stored format time  : 4.63,  = 1.49838 * stream
+format time         :10.12,  = 3.27508 * stream
+
+-- Variant  _basicfmt :
+-rwx--x--x    1 sam      users       45760 2003-09-10 20:24 /home/sam/progs/Boost/bin/BBoost//libs/format/benchmark/bench_format_basicfmt/gcc/release/bench_format_basicfmt
+printf time         :2.23
+ostream time        : 3.14,  = 1.40807 * printf
+stored format time  : 4.61,  = 1.46815 * stream
+format time         :11.33,  = 3.60828 * stream
+
+
+
+
+
+
+
+------------------- Compiler  gcc : ----------------
+-- Variant  _normal :
+printf time         :2.15
+ostream time        :4.42,  = 2.05581 * printf
+stored format time  :5.85,  = 1.32353 * stream
+format time         :11.53,  = 2.6086 * stream
+-- Variant  _no_reuse_stream :
+printf time         :2.13
+ostream time        :4.4,  = 2.06573 * printf
+stored format time  :11.1,  = 2.52273 * stream
+format time         :14.3,  = 3.25 * stream
+-- Variant  _stringstr :
+printf time         :2.01
+ostream time        :4.42,  = 2.199 * printf
+stored format time  :7.92,  = 1.79186 * stream
+format time         :12.8,  = 2.89593 * stream
+
+------------------- Compiler  intel-linux-7.1 : ----------------
+-- Variant  _normal :
+printf time         :2.08
+ostream time        :4.49,  = 2.15865 * printf
+stored format time  :5.3,  = 1.1804 * stream
+format time         :17.8,  = 3.96437 * stream
+-- Variant  _no_reuse_stream :
+printf time         :2.09
+ostream time        :4.37,  = 2.09091 * printf
+stored format time  :10.07,  = 2.30435 * stream
+format time         :14.46,  = 3.30892 * stream
+-- Variant  _stringstr :
+printf time         :1.99
+ostream time        :5.16,  = 2.59296 * printf
+stored format time  :5.83,  = 1.12984 * stream
+format time         :17.42,  = 3.37597 * stream
+
+
+
+
+// older Result with gcc-3.03 on linux :
+
+// With flag -g :
+
+/***
+printf time         :1.2
+ostream time        :2.84,  = 2.36667 * printf 
+stored format time  :8.91,  = 3.13732 * stream 
+format time         :15.35, = 5.40493 * stream 
+format3 time        :21.83, = 7.68662 * stream 
+***/
+
+
+// With flag -O
+
+/***
+printf time         :1.16
+ostream time        :1.94,  = 1.67241 * printf 
+stored format time  :3.68,  = 1.89691 * stream 
+format time         :6.31,  = 3.25258 * stream 
+format3 time        :9.04,  = 4.65979 * stream 
+***/
+
+//  ==> that's quite acceptable.
+
+// ------------------------------------------------------------------------------
diff --git a/doc/choices.html b/doc/choices.html
new file mode 100644
index 0000000..b4941d0
--- /dev/null
+++ b/doc/choices.html
@@ -0,0 +1,327 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<html>
+<head>
+  <meta http-equiv="Content-Language" content="en-us">
+  <meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
+
+  <title>Type-safe 'printf-like' format class</title>
+</head>
+
+<body bgcolor="#FFFFFF" text="#000000">
+  <h1><img align="middle" alt="boost.png (6897 bytes)" height="86" src=
+  "../../../boost.png" width="277">Type-safe 'printf-like' <b>format
+  class</b></h1>
+
+  <h2>Choices made</h2>
+
+  <p>"Le pourquoi du comment" ( - "the why of the how")</p>
+  <hr>
+
+  <h3>The syntax of the format-string</h3>
+
+  <p>Format is a new library. One of its goal is to provide a replacement for
+  printf, that means format can parse a format-string designed for printf,
+  apply it to the given arguments, and produce the same result as printf
+  would have.<br>
+  With this constraint, there were roughly 3 possible choices for the syntax
+  of the format-string :</p>
+
+  <ol>
+    <li>Use the exact same syntax of printf. It's well known by many
+    experienced users, and fits almost all needs. But with C++ streams, the
+    type-conversion character, crucial to determine the end of a directive,
+    is only useful to set some associated formatting options, in a C++
+    streams context (%x for setting hexa, etc..) It would be better to make
+    this obligatory type-conversion character, with modified meaning,
+    optional.</li>
+
+    <li>extend printf syntax while maintaining compatibility, by using
+    characters and constructs not yet valid as printf syntax. e.g. : "%1%",
+    "%[1]", "%|1$d|", .. Using begin / end marks, all sort of extension can
+    be considered.</li>
+
+    <li>Provide a non-legacy mode, in parallel of the printf-compatible one,
+    that can be designed to fit other objectives without constraints of
+    compatibilty with the existing printf syntax.<br>
+    But Designing a replacement to printf's syntax, that would be clearly
+    better, and as much powerful, is yet another task than building a format
+    class. When such a syntax is designed, we should consider splitting
+    Boost.format into 2 separate libraries : one working hand in hand with
+    this new syntax, and another supporting the legacy syntax (possibly a
+    fast version, built with safety improvement above snprintf or the
+    like).</li>
+  </ol>In the absence of a full, clever, new syntax clearly better adapted to
+  C++ streams than printf, the second approach was chosen. Boost.format uses
+  printf's syntax, with extensions (tabulations, centered alignements) that
+  can be expressed using extensions to this syntax.<br>
+  And alternate compatible notations are provided to address the weaknesses
+  of printf's :
+
+  <ul>
+    <li><i>"%<b>N</b>%"</i> as a simpler positional, typeless and optionless
+    notation.</li>
+
+    <li><i>%|spec|</i> as a way to encapsulate printf directive in movre
+    visually evident structures, at the same time making printf's
+    'type-conversion character' optional.</li>
+  </ul>
+  <hr>
+
+  <h3>Why are arguments passed through an operator rather than a function
+  call ?</h3><br>
+  The inconvenience of the operator approach (for some people) is that it
+  might be confusing. It's a usual warning that too much of overloading
+  operators gets people real confused.<br>
+  Since the use of format objects will be in specific contexts ( most often
+  right after a "cout &lt;&lt; ") and look like a formatting string followed
+  by arguments indeed :
+
+  <blockquote>
+    <pre>
+format(" %s at %s  with %s\n") % x % y % z;
+</pre>
+  </blockquote>we can hope it wont confuse people that much.
+
+  <p>An other fear about operators, is precedence problems. What if I someday
+  write <b>format("%s") % x+y</b><br>
+  instead of <i>format("%s") % (x+y)</i> ??<br>
+  It will make a mistake at compile-time, so the error will be immediately
+  detected.<br>
+  indeed, this line calls <i>tmp = operator%( format("%s"), x)</i><br>
+  and then <i>operator+(tmp, y)</i><br>
+  tmp will be a format object, for which no implicit conversion is defined,
+  and thus the call to operator+ will fail. (except if you define such an
+  operator, of course). So you can safely assume precedence mistakes will be
+  noticed at compilation.</p>
+
+  <p><br>
+  On the other hand, the function approach has a true inconvenience. It needs
+  to define lots of template function like :</p>
+
+  <blockquote>
+    <pre>
+template &lt;class T1, class T2,  .., class TN&gt; 
+string format(string s,  const T1&amp; x1, .... , const T1&amp; xN);
+
+</pre>
+  </blockquote>and even if we define those for N up to 500, that is still a
+  limitation, that C's printf does not have.<br>
+  Also, since format somehow emulates printf in some cases, but is far from
+  being fully equivalent to printf, it's best to use a radically different
+  appearance, and using operator calls succeeds very well in that !
+
+  <p><br>
+  Anyhow, if we actually chose the formal function call templates system, it
+  would only be able to print Classes T for which there is an</p>
+
+  <blockquote>
+    <pre>
+operator&lt;&lt; ( stream,   const T&amp;)
+</pre>
+  </blockquote>Because allowing both const and non const produces a
+  combinatorics explosion - if we go up to 10 arguments, we need 2^10
+  functions.<br>
+  (providing overloads on T&amp; / const T&amp; is at the frontier of defects
+  of the C++ standard, and thus is far from guaranteed to be supported. But
+  right now several compilers support those overloads)<br>
+  There is a lot of chances that a class which only provides the non-const
+  equivalent is badly designed, but yet it is another unjustified restriction
+  to the user.<br>
+  Also, some manipulators are functions, and can not be passed as const
+  references. The function call approach thus does not support manipulators
+  well.
+
+  <p>In conclusion, using a dedicated binary operator is the simplest, most
+  robust, and least restrictive mechanism to pass arguments when you can't
+  know the number of arguments at compile-time.</p>
+  <hr>
+
+  <h3>Why operator% rather than a member function 'with(..)'
+  ??</h3>technically,
+
+  <blockquote>
+    <pre>
+format(fstr) % x1 % x2 % x3;
+</pre>
+  </blockquote>has the same structure as
+
+  <blockquote>
+    <pre>
+format(fstr).with( x1 ).with( x2 ).with( x3 );
+</pre>
+  </blockquote>which does not have any precedence problem. The only drawback,
+  is it's harder for the eye to catch what is done in this line, than when we
+  are using operators. calling .with(..), it looks just like any other line
+  of code. So it may be a better solution, depending on tastes. The extra
+  characters, and overall cluttered aspect of the line of code using
+  'with(..)' were enough for me to opt for a true operator.
+  <hr>
+
+  <h3>Why operator% rather than usual formatting operator&lt;&lt; ??</h3>
+
+  <ul>
+    <li>because passing arguments to a format object is *not* the same as
+    sending variables, sequentially, into a stream, and because a format
+    object is not a stream, nor a manipulator.<br>
+      We use an operator to pass arguments. format will use them as a
+      function would, it simply takes arguments one by one.<br>
+      format objects can not provide stream-like behaviour. When you try to
+      implement a format object that acts like a manipulator, returning a
+      stream, you make the user beleive it is completely like a
+      stream-manipulator. And sooner or later, the user is deceived by this
+      point of view.<br>
+      The most obvious example of that difference in behaviour is
+
+      <blockquote>
+        <pre>
+cout &lt;&lt; format("%s %s ") &lt;&lt; x;
+cout &lt;&lt; y ;  // uh-oh, format is not really a stream manipulator
+</pre>
+      </blockquote>
+    </li>
+
+    <li>precedence of % is higher than that of &lt;&lt;. It can be viewd as a
+    problem, because + and - thus needs to be grouped inside parentheses,
+    while it is not necessary with '&lt;&lt;'. But if the user forgets, the
+    mistake is catched at compilation, and hopefully he won't forget
+    again.<br>
+      On the other hand, the higher precedence makes format's behaviour very
+      straight-forward.
+
+      <blockquote>
+        <pre>
+cout &lt;&lt; format("%s %s ") % x % y &lt;&lt; endl;
+</pre>
+      </blockquote>is treated exaclt like :
+
+      <blockquote>
+        <pre>
+cout &lt;&lt; ( format("%s %s ") % x % y ) &lt;&lt; endl;
+</pre>
+      </blockquote>So using %, the life of a format object does not interfere
+      with the surrounding stream context. This is the simplest possible
+      behaviour, and thus the user is able to continue using the stream after
+      the format object.<br>
+      <br>
+      With operator&lt;&lt;, things are much more problematic in this
+      situation. This line :
+
+      <blockquote>
+        <pre>
+cout &lt;&lt; format("%s %s ") &lt;&lt;  x  &lt;&lt;  y &lt;&lt; endl;
+</pre>
+      </blockquote>is understood as :
+
+      <blockquote>
+        <pre>
+( ( ( cout &lt;&lt; format("%s %s ") ) &lt;&lt; x ) &lt;&lt;  y ) &lt;&lt; endl;
+</pre>
+      </blockquote>Several alternative implementations chose
+      operator&lt;&lt;, and there is only one way to make it work :<br>
+      the first call to
+
+      <blockquote>
+        <pre>
+operator&lt;&lt;( ostream&amp;, format const&amp;)
+</pre>
+      </blockquote>returns a proxy, encapsulating both the final destination
+      (cout) and the format-string information<br>
+      Passing arguments to format, or to the final destination after
+      completion of the format are indistinguishable. This is a problem.
+
+      <p>I examined several possible implementations, and none is completely
+      satsifying.<br>
+      E.g. : In order to catch users mistake, it makes sense to raise
+      exceptions when the user passes too many arguments. But in this
+      context, supplementary arguments are most certainly aimed at the final
+      destination. There are several choices here :</p>
+
+      <ul>
+        <li>You can give-up detection of arity excess, and have the proxy's
+        template member operator&lt;&lt;( const T&amp;) simply forward all
+        supplementary arguments to cout.</li>
+
+        <li>Require the user to close the format arguments with a special
+        manipulator, 'endf', in this way :
+
+          <blockquote>
+            <pre>
+cout &lt;&lt; format("%s %s ") &lt;&lt;  x  &lt;&lt;  y &lt;&lt; endf &lt;&lt; endl;
+</pre>
+          </blockquote>You can define endf to be a function that returns the
+          final destination stored inside the proxy. Then it's okay, after
+          endf the user is calling &lt;&lt; on cout again.
+        </li>
+
+        <li>An intermediate solution, is to adress the most frequent use,
+        where the user simply wants to output one more manipulator item to
+        cout (a std::flush, or endl, ..)
+
+          <blockquote>
+            <pre>
+cout &lt;&lt; format("%s %s \n") &lt;&lt;  x  &lt;&lt;  y &lt;&lt; flush ;
+</pre>
+          </blockquote>Then, the solution is to overload the operator&lt;&lt;
+          for manipulators. This way You don't need endf, but outputting a
+          non-manipulator item right after the format arguments is a mistake.
+        </li>
+      </ul><br>
+      The most complete solution is the one with the endf manipualtor. With
+      operator%, there is no need for this end-format function, plus you
+      instantly see which arguments are going into the format object, and
+      which are going to the stream.
+    </li>
+
+    <li>Esthetically : '%' is the same letter as used inside the
+    format-string. That is quite nice to have the same letter used for
+    passing each argument. '&lt;&lt;' is 2 letters, '%' is one. '%' is also
+    smaller in size. It overall improves visualisation (we see what goes with
+    what) :
+
+      <blockquote>
+        <pre>
+cout &lt;&lt; format("%s %s %s") %x %y %z &lt;&lt; "And  avg is" &lt;&lt; format("%s\n") %avg;
+</pre>
+      </blockquote>compared to :
+
+      <blockquote>
+        <pre>
+cout &lt;&lt; format("%s %s %s") &lt;&lt; x &lt;&lt; y &lt;&lt; z &lt;&lt; endf &lt;&lt;"And avg is" &lt;&lt; format("%s\n") &lt;&lt; avg;
+</pre>
+      </blockquote>"&lt;&lt;" misleadingly puts the arguments at the same
+      level as any object passed to the stream.
+    </li>
+
+    <li>python also uses % for formatting, so you see it's not so "unheard
+    of" ;-)</li>
+  </ul>
+  <hr>
+
+  <h3>Why operator% rather than operator(), or operator[] ??</h3>
+
+  <p>operator() has the merit of being the natural way to send an argument
+  into a function. And some think that operator[] 's meaning apply well to
+  the usage in format.<br>
+  They're as good as operator% technically, but quite ugly. (that's a matter
+  of taste)<br>
+  And deepd down, using operator% for passing arguments that were referred to
+  by "%" in the format string seems much more natural to me than using those
+  operators.</p>
+  <hr>
+
+  <p><a href="http://validator.w3.org/check?uri=referer"><img border="0" src=
+  "../../../doc/images/valid-html401.png" alt="Valid HTML 4.01 Transitional"
+  height="31" width="88"></a></p>
+
+  <p>Revised 
+  <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->02 December, 2006<!--webbot bot="Timestamp" endspan i-checksum="38510" --></p>
+
+  <p><i>Copyright &copy; 2001 Samuel Krempp</i></p>
+
+  <p><i>Distributed under the Boost Software License, Version 1.0. (See
+  accompanying file <a href="../../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or
+  copy at <a href=
+  "http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>)</i></p>
+</body>
+</html>
diff --git a/doc/format.html b/doc/format.html
new file mode 100644
index 0000000..5615fdf
--- /dev/null
+++ b/doc/format.html
@@ -0,0 +1,1059 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<html>
+<head>
+  <meta http-equiv="Content-Language" content="en-us">
+  <meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
+
+  <title>The Boost Format library</title>
+</head>
+
+<body bgcolor="white" text="black">
+  <h1><img align="middle" alt="boost.png (6897 bytes)" height="86" src=
+  "../../../boost.png" width="277">The Boost Format library</h1>
+
+  <p>The <code><a href=
+  "../../../boost/format.hpp">&lt;boost/format.hpp&gt;</a></code> format
+  class provides printf-like formatting, in a type-safe manner which allows
+  output of user-defined types.<br></p>
+
+  <ul>
+    <li><a href="#synopsis">Synopsis</a></li>
+
+    <li><a href="#how_it_works">How it works</a></li>
+
+    <li><a href="#examples">Examples</a></li>
+
+    <li>
+      <a href="#syntax">Syntax</a>
+
+      <ul>
+        <li><a href="#printf_directives">printf format-specification
+        syntax</a></li>
+
+        <li><a href="#printf_differences">Incompatibilities with
+        printf</a></li>
+      </ul>
+    </li>
+
+    <li><a href="#manipulators">Manipulators and the internal stream
+    state</a></li>
+
+    <li><a href="#user-defined">User-defined types</a></li>
+
+    <li><a href="#alternatives">Alternatives</a></li>
+
+    <li><a href="#exceptions">Exceptions</a></li>
+
+    <li><a href="#performance">Performance</a></li>
+
+    <li><a href="#extract">Class Interface Extract</a></li>
+
+    <li><a href="#rationale">Rationale</a></li>
+  </ul><a name="synopsis" id="synopsis"></a>
+  <hr>
+
+  <h2>Synopsis</h2>
+
+  <p>A format object is constructed from a format-string, and is then given
+  arguments through repeated calls to <i>operator%</i>.<br>
+  Each of those arguments are then converted to strings, who are in turn
+  combined into one string, according to the format-string.</p>
+
+  <blockquote>
+    <pre>
+cout &lt;&lt; boost::format("writing %1%,  x=%2% : %3%-th try") % "toto" % 40.23 % 50; 
+     // prints "writing toto,  x=40.230 : 50-th try"
+</pre>
+  </blockquote><a name="how_it_works" id="how_it_works"></a>
+  <hr>
+
+  <h2>How it works</h2>
+
+  <ol>
+    <li>When you call <i>format(s)</i>, where s is the format-string, it
+    constructs an object, which parses the format string and look for all
+    directives in it and prepares internal structures for the next step.</li>
+
+    <li>Then, either immediately, as in
+
+      <blockquote>
+        <pre>
+cout &lt;&lt; format("%2% %1%") % 36 % 77;
+</pre>
+      </blockquote>or later on, as in
+
+      <blockquote>
+        <pre>
+format fmter("%2% %1%");
+fmter % 36; fmter % 77;
+</pre>
+      </blockquote>you <i>feed</i> variables into the formatter.<br>
+      those variables are dumped into an internal stream, which state is set
+      according to the given formatting options in the format-string -if
+      there are any-, and the format object stores the string results for the
+      last step.
+    </li>
+
+    <li>Once all arguments have been fed you can dump the format object to a
+    stream, or get its string value by using the <i>str()</i> member
+    function, or the free function <i>str(const format&amp; )</i> in
+    namespace <i>boost</i>. The result string stays accessible in the format
+    object until another argument is passed, at which time it is
+    reinitialised.
+
+      <blockquote>
+        <pre>
+
+// fmter was previously created and fed arguments, it can print the result :
+cout &lt;&lt; fmter ;  
+
+// You can take the string result :
+string s  = fmter.str();
+
+// possibly several times :
+s = fmter.str( );
+
+// You can also do all steps at once :
+cout &lt;&lt; boost::format("%2% %1%") % 36 % 77; 
+
+// using the str free function :
+string s2 = str( format("%2% %1%") % 36 % 77 );
+
+</pre>
+      </blockquote>
+    </li>
+
+    <li>Optionnally, after step 3, you can re-use a format object and restart
+    at step2 : <i>fmter % 18 % 39;</i><br>
+    to format new variables with the same format-string, saving the expensive
+    processing involved at step 1.</li>
+  </ol>All in all, the format class translates a format-string (with
+  eventually printf-like directives) into operations on an internal stream,
+  and finally returns the result of the formatting, as a string, or directly
+  into an output stream. <a name="examples" id="examples"></a>
+  <hr>
+
+  <h2>Examples</h2>
+
+  <blockquote>
+    <pre>
+using namespace std;
+using boost::format;
+using boost::io::group;
+</pre>
+  </blockquote>
+
+  <ul>
+    <li>Simple output, with reordering :
+
+      <blockquote>
+        <pre>
+
+cout &lt;&lt; format("%1% %2% %3% %2% %1% \n") % "11" % "22" % "333"; // 'simple' style.
+
+</pre>
+      </blockquote>It prints : "11 22 333 22 11 \n"
+    </li>
+
+    <li>More precise formatting, with Posix-printf positional directives :
+
+      <blockquote>
+        <pre>
+
+cout &lt;&lt; format("(x,y) = (%1$+5d,%2$+5d) \n") % -23 % 35;     // Posix-Printf style
+
+</pre>
+      </blockquote>It prints : "(x,y) = ( -23, +35) \n"
+    </li>
+
+    <li>classical printf directive, no reordering :
+
+      <blockquote>
+        <pre>
+
+cout &lt;&lt; format("writing %s,  x=%s : %d-th step \n") % "toto" % 40.23 % 50; 
+
+</pre>
+      </blockquote>It prints : "writing toto, x=40.23 : 50-th step \n"
+    </li>
+
+    <li>Several ways to express the same thing :
+
+      <blockquote>
+        <pre>
+
+cout &lt;&lt; format("(x,y) = (%+5d,%+5d) \n") % -23 % 35;
+cout &lt;&lt; format("(x,y) = (%|+5|,%|+5|) \n") % -23 % 35;
+
+cout &lt;&lt; format("(x,y) = (%1$+5d,%2$+5d) \n") % -23 % 35;
+cout &lt;&lt; format("(x,y) = (%|1$+5|,%|2$+5|) \n") % -23 % 35;
+
+</pre>
+      </blockquote>all those print : "(x,y) = ( -23, +35) \n"
+    </li>
+
+    <li>Using manipulators to modify the format-string :
+
+      <blockquote>
+        <pre>
+
+format fmter("_%1$+5d_ %1$d \n");
+
+format fmter2("_%1%_ %1% \n");
+fmter2.modify_item(1, group(showpos, setw(5)) ); 
+
+cout &lt;&lt; fmter % 101 ;
+cout &lt;&lt; fmter2 % 101 ;
+
+</pre>
+      </blockquote>Both print the same : "_ +101_ 101 \n"
+    </li>
+
+    <li>Using manipulators with arguments :
+
+      <blockquote>
+        <pre>
+
+cout &lt;&lt; format("_%1%_ %1% \n") % group(showpos, setw(5), 101);
+
+</pre>
+      </blockquote>The manipulators are applied at each occurrence of %1%, and
+      thus it prints : "_ +101_ +101 \n"
+    </li>
+
+    <li>New formatting feature : 'absolute tabulations', useful inside loops,
+    to insure a field is printed at the same position from one line to the
+    next, even if the widthes of the previous arguments can vary a lot.
+
+      <blockquote>
+        <pre>
+
+for(unsigned int i=0; i &lt; names.size(); ++i)
+    cout &lt;&lt; format("%1%, %2%, %|40t|%3%\n") % names[i] % surname[i] % tel[i];
+
+</pre>
+      </blockquote>For some std::vector <i>names</i>, <i>surnames</i>, and
+      <i>tel</i> (see sample_new_features.cpp) it prints :
+
+      <blockquote>
+        <pre>
+Marc-Fran&ccedil;ois Michel, Durand,           +33 (0) 123 456 789
+Jean, de Lattre de Tassigny,            +33 (0) 987 654 321
+</pre>
+      </blockquote>
+    </li>
+  </ul>
+  <hr>
+
+  <h2>Sample Files</h2>
+
+  <p>The program <a href=
+  "../example/sample_formats.cpp">sample_formats.cpp</a> demonstrates simple
+  uses of <b>format</b>.<br></p>
+
+  <p><a href="../example/sample_new_features.cpp">sample_new_features.cpp</a>
+  illustrates the few formatting features that were added to printf's syntax
+  such as simple positional directives, centered alignment, and
+  'tabulations'.<br></p>
+
+  <p><a href="../example/sample_advanced.cpp">sample_advanced.cpp</a>
+  demonstrates uses of advanced features, like reusing, and modifying, format
+  objects, etc..<br></p>
+
+  <p>And <a href="../example/sample_userType.cpp">sample_userType.cpp</a>
+  shows the behaviour of the <b>format</b> library on user-defined
+  types.</p><a name="syntax" id="syntax"></a>
+  <hr>
+
+  <h2>Syntax</h2>
+
+  <p><b>boost::format(</b> format-string <b>) %</b> arg1 <b>%</b> arg2
+  <b>%</b> ... <b>%</b> argN</p>
+
+  <p>The <i>format-string</i> contains text in which special directives will
+  be replaced by strings resulting from the formatting of the given
+  arguments.<br>
+  The legacy syntax in the C and C++ worlds is the one used by printf, and
+  thus format can use directly printf format-strings, and produce the same
+  result (in almost all cases. see <a href=
+  "#printf_differences">Incompatibilities with printf</a> for details)<br>
+  This core syntax was extended, to allow new features, but also to adapt to
+  the C++ streams context. Thus, format accepts several forms of directives
+  in format-strings :</p>
+
+  <ul>
+    <li>Legacy printf format strings : <b>%</b><i>spec</i> where <i>spec</i>
+    is a <a href="#printf_directives">printf format specification</a><br>
+    <i>spec</i> passes formatting options, like width, alignment, numerical
+    base used for formatting numbers, as well as other specific flags. But
+    the classical <i>type-specification</i> flag of printf has a weaker
+    meaning in format. It merely sets the appropriate flags on the internal
+    stream, and/or formatting parameters, but does not require the
+    corresponding argument to be of a specific type.<br>
+    e.g. : the specification <i>2$x</i>, meaning "print argument number 2,
+    which is an integral number, in hexa" for printf, merely means "print
+    argument 2 with stream basefield flags set to <i>hex</i>" for
+    format.</li>
+
+    <li><b>%|</b><i>spec</i><b>|</b> where <i>spec</i> is a printf format
+    specification.<br>
+    This pipe-delimited syntax is introduced, to improve the readability of the
+    format-string, but primarily, to make the <i>type-conversion
+    character</i> optional in <i>spec</i>. This information is not necessary
+    with C++ variables, but with direct printf syntax, it is necessary to
+    always give a type-conversion character, merely because this character is
+    crucial to determine the end of a format-specification.<br>
+    e.g. : "%|-5|" will format the next variable with width set to 5, and
+    left-alignment just like the following printf directives : "%-5g",
+    "%-5f", "%-5s" ..</li>
+
+    <li><b>%</b><i>N</i><b>%</b><br>
+    This simple positional notation requests the formatting of the
+    <i>N</i>-th argument - wihout any formatting option.<br>
+    (It's merely a shortcut to Printf's positional directives (like
+    "%<i>N</i>$s"), but a major benefit is that it's much more readable, and
+    does not use a "type-conversion" character)</li>
+  </ul>On top of the standard printf format specifications, new features were
+  implemented, like centered alignment. See <a href="#new_directives">new
+  format specification</a> for details. <a name="printf_directives" id=
+  "printf_directives"></a>
+
+  <h3>printf format specifications</h3>
+
+  <p>The printf format specifications supported by Boost.format follows the
+  Unix98 <a href=
+  "http://www.opengroup.org/onlinepubs/7908799/xsh/fprintf.html">Open-group
+  printf</a> precise syntax, rather than the standard C printf, which does
+  not support positional arguments. (Common flags have the same meaning in
+  both, so it should not be a headache for anybody)<br>
+  <i>Note that it is an error to use positional format specifications</i>
+  (e.g. <i>%3$+d</i>) <i>mixed with non-positional ones</i> (e.g. <i>%+d</i>)
+  <i>in the same format string.</i><br>
+  In the Open-group specification, referring to the same argument several
+  times (e.g. <i>"%1$d %1$d"</i>) has undefined behaviour. Boost.format's
+  behaviour in such cases is to allow each argument to be reffered to any
+  number of times. The only constraint is that it expects exactly <i>P</i>
+  arguments, <i>P</i> being the maximum argument number used in the format
+  string. (e.g., for "%1$d %10$d", <i>P</i> == 10 ).<br>
+  Supplying more, or less, than <i>P</i> arguments raises an exception.
+  (unless it was set otherwise, see <a href="#exceptions">exceptions</a>)</p>
+
+  <p>A specification <i>spec</i> has the form: 
+      <pre>    [ <i>N</i><b>$</b> ] [ <i>flags</i> ] [ <i>width</i> ] [ <b>.</b> <i>precision</i> ] [ <i>argument-type</i> ] <i>conversion-specifier</i></pre>
+
+  Fields inside square brackets are optional.  Each of those fields are
+  explained one by one in the following list:</p>
+
+  <ul>
+    <li><i>N</i> <b>$</b> (optional field) specifies that the format
+    specification applies to the <i>N</i>-th argument (it is called a
+    <i>positional format specification</i>).<br>
+    If this is not present, arguments are taken one by one. (and it is then
+    an error to later supply an argument number)</li><br />
+
+    <li>
+      <i>flags</i> is a sequence of any of these:
+
+      <blockquote>
+        <table border="1" cellpadding="5" summary="">
+          <tr>
+            <td><b>Flag</b></td>
+
+            <td><b>Meaning</b></td>
+
+            <td><b>effect on internal stream</b></td>
+          </tr>
+
+          <tr>
+            <td><b>'-'</b></td>
+
+            <td>left alignment</td>
+
+            <td>N/A (applied later on the string)</td>
+          </tr>
+
+          <tr>
+            <td><b>'='</b></td>
+
+            <td>centered alignment</td>
+
+            <td>N/A (applied later on the string)<br>
+            <i>- note : added feature, not in printf -</i></td>
+          </tr>
+
+          <tr>
+            <td><b>'_'</b></td>
+
+            <td>internal alignment</td>
+
+            <td>sets internal alignment<br>
+            <i>- note : added feature, not in printf -</i></td>
+          </tr>
+
+          <tr>
+            <td><b>'+'</b></td>
+
+            <td>show sign even for positive numbers</td>
+
+            <td>sets <i>showpos</i></td>
+          </tr>
+
+          <tr>
+            <td><b>'#'</b></td>
+
+            <td>show numerical base, and decimal point</td>
+
+            <td>sets <i>showbase</i> and <i>showpoint</i></td>
+          </tr>
+
+          <tr>
+            <td><b>'0'</b></td>
+
+            <td>pad with 0's (inserted after sign or base indicator)</td>
+
+            <td>if not left-aligned, calls <i>setfill('0')</i> and sets
+            <i>internal</i><br>
+            Extra actions are taken after stream conversion to handle
+            <a href="#user-defined">user-defined output</a>.</td>
+          </tr>
+
+          <tr>
+            <td><b>' '</b></td>
+
+            <td>if the string does not begin with <i>+</i> or <i>-</i>,
+            insert a <i>space</i> before the converted string</td>
+
+            <td>N/A (applied later on the string)<br>
+            Different to printf's behaviour : it is not affected by internal
+            alignment</td>
+          </tr>
+        </table>
+      </blockquote><br />
+    </li>
+
+    <li><i>width</i> specifies a minimal width for the string resulting form
+    the conversion. If necessary, the string will be padded with alignment
+    and fill characters either set on the stream via manipulators, or
+    specified by the format-string (e.g. flags '0', '-', ..)<br>
+    Note that width is not just set on the conversion stream. To support
+    output of <a href="#user-defined">user-defined types</a> (that might call
+    <i>operator&lt;&lt;</i> many times on several members), the width is
+    handled after stream conversion of the whole argument object, in the
+    format class code.</li><br />
+
+    <li>
+      <i>precision</i> (preceded by a point), sets the stream's
+      <i>precision</i>
+
+      <ul>
+        <li>When outputting a floatting type number, it sets the maximum
+        number of digits
+
+          <ul>
+            <li>after decimal point when in fixed or scientific mode</li>
+
+            <li>in total when in default mode ('<i>general mode</i>', like
+            <i>%g</i>)</li>
+          </ul>
+        </li>
+
+        <li>When used with type-char <b>s</b> or <b>S</b> it takes another
+        meaning : the conversion string is truncated to the <i>precision</i>
+        first chars. (Note that the eventual padding to <i>width</i> is done
+        after truncation.)</li>
+      </ul><br />
+    </li>
+
+    <li>
+        <i>argument-type</i> is used by the printf family to properly process
+        the arguments being passed in through varargs.  With <code>boost::format</code>
+        the arguments are fed into format through <code>operator %</code> which
+        allows the template to carry the argument type.  Therefore the classical
+        printf style argument type is consumed and ignored.
+        Argument-types <code>hh</code>, <code>h</code>, <code>l</code>, <code>ll</code>, <code>j</code>, 
+        <code>z</code>, and <code>L</code> are recognized, as are the Microsoft extensions <code>w</code>,
+        <code>I</code> (capital i), <code>I32</code>, and <code>I64</code>.  Argument-type <code>t</code> 
+        from the ISO C99 standard is not recognized as an argument type, as it has been in use as a
+        conversion specifier for tabular output for many years in <code>boost::format</code>.
+    </li><br />
+
+    <li>
+      <i>conversion-specifier</i> does <b>not</b> impose the concerned argument 
+      to be of a restricted set of types, but merely sets the ios flags that are
+      associated with a type specification:
+
+      <blockquote>
+        <table border="1" cellpadding="5" summary="">
+          <tr>
+            <td><b>conversion-specifier</b></td>
+
+            <td><b>Meaning</b></td>
+
+            <td><b>effect on stream</b></td>
+          </tr>
+
+          <tr>
+            <td><b>b</b></td>
+
+            <td>boolean string output</td>
+
+            <td>sets <i>boolalpha</i>; only works for type <code>bool</code><br />
+            To customize the resulting string, see 
+            <a href="http://en.cppreference.com/w/cpp/locale/numpunct/truefalsename">std::numpunct</a>.
+          </tr>
+
+          <tr>
+            <td><b>p or x</b></td>
+
+            <td>hexadecimal output</td>
+
+            <td>sets <i>hex</i></td>
+          </tr>
+
+          <tr>
+            <td><b>o</b></td>
+
+            <td>octal output</td>
+
+            <td>sets <i>oct</i></td>
+          </tr>
+
+          <tr>
+            <td><b>a</b></td>
+
+            <td>hexadecimal exponent notation</td>
+
+            <td>sets floatfield bits to <i>scientific</i> | <i>fixed</i> (which is equivalent to <i>hexfloat</i>)</td>
+          </tr>
+
+          <tr>
+            <td><b>e</b></td>
+
+            <td>scientific float format</td>
+
+            <td>sets floatfield bits to <i>scientific</i></td>
+          </tr>
+
+          <tr>
+            <td><b>f</b></td>
+
+            <td>fixed float format</td>
+
+            <td>sets floatfield bits to <i>fixed</i></td>
+          </tr>
+
+          <tr>
+            <td><b>g</b></td>
+
+            <td>general -default- float format</td>
+
+            <td><b>unset</b> all floatfield bits</td>
+          </tr>
+
+          <tr>
+            <td><b>X, A, E, F</b> or <b>G</b></td>
+
+            <td>same effect as their lowercase counterparts, but using
+            uppercase letters for number outputs. (exponents, hex digits,
+            ..)</td>
+
+            <td>same effects as <i>'x'</i>, <i>'a'</i>, <i>'e'</i>, <i>'f'</i>, or <i>'g'</i> respectively,
+            <b>plus</b> <i>uppercase</i></td>
+          </tr>
+
+          <tr>
+            <td><b>d, i</b> or <b>u</b></td>
+
+            <td><b>decimal</b> type output</td>
+
+            <td>sets basefield bits to <i>dec</i></td>
+          </tr>
+
+          <tr>
+            <td><b>s</b> or <b>S</b></td>
+
+            <td>string output</td>
+
+            <td><i>precision</i> specification is unset, and its value goes
+            to an internal field for later 'truncation'. (see
+            <i>precision</i> explanation above)</td>
+          </tr>
+
+          <tr>
+            <td><b>c</b> or <b>C</b></td>
+
+            <td>1-character output</td>
+
+            <td>only the first character of the conversion string is
+            used.</td>
+          </tr>
+
+          <tr>
+            <td><b>%</b></td>
+
+            <td>print the character <i>%</i></td>
+
+            <td>N/A</td>
+          </tr>
+        </table>
+      </blockquote>
+
+      <p>Note that the 'n' conversion-specifier is ignored (and so is the
+      corresponding argument), because it does not fit in this context.</p>
+    </li>
+  </ul><a name="new_directives" id="new_directives"></a>
+
+  <h3>new format-specifications</h3>
+
+  <ul>
+    <li>as stated in the flags table, centered and internal alignment flags
+    (' <i>=</i> ', and ' <i>_</i> ') were added.</li>
+
+    <li><i><b>%{</b>n</i><b>t}</b> , where <i>n</i> is a positive number,
+    inserts an <i>absolute tabulation</i>. It means that format will, if
+    needed, fill the string with characters, until the length of the string
+    created so far reaches <i>n</i> characters. (see <a href=
+    "#examples">examples</a> )</li>
+
+    <li><b>%|</b><i>n</i><b>T</b><i>X</i><b>|</b> inserts a tabulation in the
+    same way, but using <i>X</i> as fill character instead of the current
+    'fill' char of the stream (which is <i>space</i> for a stream in default
+    state)</li>
+  </ul><a name="printf_differences" id="printf_differences"></a>
+
+  <h2>Differences of behaviour vs printf</h2>Suppose you have variables
+  <i>x1, x2</i> (built_in types, supported by C's printf),<br>
+  and a format string <i>s</i> intended for use with a printf function this
+  way :
+
+  <blockquote>
+    <pre>
+printf(s, x1, x2);
+</pre>
+  </blockquote><br>
+  In almost all cases, the result will be the same as with this command :
+
+  <blockquote>
+    <pre>
+cout &lt;&lt; format(s) % x1 % x2;
+</pre>
+  </blockquote>
+
+  <p>But because some printf format specifications don't translate well into
+  stream formatting options, there are a few notable imperfections in the way
+  Boost.format emulates printf.<br>
+  In any case, the <i>format</i> class should quietly ignore the unsupported
+  options, so that printf format-strings are always accepted by format and
+  produce almost the same output as printf.</p><br>
+  Here is the full list of such differences :
+
+  <ul>
+    <li><b>'0'</b> and <b>' '</b> options : printf ignores these options for
+    non numeric conversions, but format applies them to all types of
+    variables. (so it is possible to use those options on user-defined types,
+    e.g. a Rational class, etc..)</li>
+
+    <li><b>precision</b> for integral types arguments has a special meaning
+    for printf :<br>
+    <i>printf( "(%5.3d)" , 7 ) ;</i> prints &laquo; ( 007) &raquo;<br>
+    While format, like streams, ignores the precision parameter for integral
+    types conversions.</li>
+
+    <li>the <b>'</b> printf option (<i>format with thousands grouping
+    characters)</i>) has no effect in format.</li>
+
+    <li>Width or precision set to asterisk (<i>*</i>) are used by printf to
+    read this field from an argument. e.g.
+    <i>printf("%1$d:%2$.*3$d:%4$.*3$d\n", hour, min, precision, sec);</i><br>
+    This class does not support this mechanism for now. so such precision or
+    width fields are quietly ignored by the parsing.</li>
+
+    <li>argument-type is ignored</li>
+  </ul>Also, note that the special <b>'n'</b> type-specification (used to
+  tell printf to save in a variable the number of characters output by the
+  formatting) has no effect in format.<br>
+  Thus format strings containing this type-specification should produce the
+  same converted string by printf or format. It will not cause differences in
+  the formatted strings between printf and format.<br>
+  To get the number of characters in the formatted string using Boost.Format,
+  you can use the <i>size()</i> member function :
+
+  <blockquote>
+    <pre>
+format formatter("%+5d");
+cout &lt;&lt; formatter % x;
+unsigned int n = formatter.size();
+</pre>
+  </blockquote><a name="user-defined" id="user-defined"></a>
+  <hr>
+
+  <h2>User-defined types output</h2>
+
+  <p>All flags which are translated into modification to the stream state act
+  recursively within user-defined types. ( the flags remain active, and so
+  does the desired format option, for each of the '&lt;&lt;' operations that
+  might be called by the user-defined class)</p>e.g., with a Rational class,
+  we would have something like :
+
+  <blockquote>
+    <pre>
+Rational ratio(16,9);
+cerr &lt;&lt; format("%#x \n")  % ratio;  // -&gt; "0x10/0x9 \n"
+</pre>
+  </blockquote>
+
+  <p>It's a different story for other formatting options. For example,
+  setting width applies to the final output produced by the object, not to
+  each of its internal outputs, and that's fortunate :</p>
+
+  <blockquote>
+    <pre>
+cerr &lt;&lt; format("%-8d")  % ratio;  // -&gt; "16/9    "      and not    "16      /9       "
+cerr &lt;&lt; format("%=8d")  % ratio;  // -&gt; "  16/9  "      and not    "   16   /    9   "
+</pre>
+  </blockquote>
+
+  <p><br>
+  But so does the 0 and ' ' options (contrarily to '+' which is directly
+  translated to the stream state by <i>showpos</i>. But no such flags exist
+  for the zero and space printf options)<br>
+  and that is less natural :</p>
+
+  <blockquote>
+    <pre>
+cerr &lt;&lt; format("%+08d \n")  % ratio;  // -&gt; "+00016/9"
+cerr &lt;&lt; format("% 08d \n")  % ratio;  // -&gt; "000 16/9"
+</pre>
+  </blockquote>It is possible to obtain a better behaviour by carefully
+  designing the Rational's <i>operator&lt;&lt;</i> to handle the stream's
+  width, alignment and <i>showpos</i> paramaters by itself. This is
+  demonstrated in <a href=
+  "../example/sample_userType.cpp">sample_userType.cpp</a>. <a name=
+  "manipulators" id="manipulators"></a>
+  <hr>
+
+  <h3>Manipulators, and internal stream state</h3>
+
+  <p>The internal stream state of <b>format</b> is saved before and restored
+  after output of an argument; therefore, the modifiers are not sticky and
+  affect only the argument they are applied to.<br>
+  The default state for streams, as stated by the standard, is : precision 6,
+  width 0, right alignment, and decimal flag set.</p>
+
+  <p>The state of the internal <b>format</b> stream can be changed by
+  manipulators passed along with the argument; via the <i>group</i> function,
+  like that :</p>
+
+  <blockquote>
+    <pre>
+cout &lt;&lt; format("%1% %2% %1%\n") % group(hex, showbase, 40) % 50; // prints "0x28 50 0x28\n"
+</pre>
+  </blockquote>
+
+  <p><br>
+  When passing N items inside a 'group' Boost.format needs to process
+  manipulators diferently from regular argument, and thus using group is
+  subject to the following constraints :</p>
+
+  <ol>
+    <li>the object to be printed must be passed as the last item in the
+    group</li>
+
+    <li>the first N-1 items are treated as manipulators, and if they do
+    produce output, it is discarded</li>
+  </ol>
+
+  <p>Such manipulators are passed to the streams right before the following
+  argument, at every occurrence. Note that formatting options specified within
+  the format string are overridden by stream state modifiers passed this way.
+  For instance in the following code, the <i>hex</i> manipulator has priority
+  over the <i>d</i> type-specification in the format-string which would set
+  decimal output :</p>
+
+  <blockquote>
+    <pre>
+cout &lt;&lt; format("%1$d %2% %1%\n") % group(hex, showbase, 40) % 50; 
+// prints "0x28 50 0x28\n"
+</pre>
+  </blockquote><a name="alternatives" id="alternatives"></a>
+
+  <h2>Alternatives</h2>
+
+  <ul>
+    <li><b>printf</b> is the classical alternative, that is not type safe and
+    not extendable to user-defined types.</li>
+
+    <li>ofrstream.cc by Karl Nelson's design was a big source of inspiration
+    to this format class.</li>
+
+    <li>James Kanze's library has a format class (in
+    <i>srcode/Extended/format</i> ) which looks very well polished. Its
+    design has in common with this class the use of internal stream for the
+    actual conversions, as well as using operators to pass arguments. (but
+    his class, as ofrstream, uses <i>operator&lt;&lt;</i> rather <i>than
+    operator%</i> )</li>
+
+    <li><a href="http://groups.yahoo.com/group/boost/files/format3/">Karl
+    Nelson's library</a> was intented as demonstration of alternative
+    solutions in discussions on Boost's list for the design of
+    Boost.format.</li>
+
+    <li><a href="http://fmtlib.net/latest/index.html">{fmt}</a> by Victor Zverovich.</li>
+  </ul><a name="exceptions" id="exceptions"></a>
+  <hr>
+
+  <h2>Exceptions</h2>
+
+  <p>Boost.format enforces a number of rules on the usage of format objects.
+  The format-string must obeys the syntax described above, the user must
+  supply exactly the right number of arguments before outputting to the final
+  destination, and if using modify_item or bind_arg, items and arguments
+  index must not be out of range.<br>
+  When format detects that one of these rules is not satisfied, it raises a
+  corresponding exception, so that the mistakes don't go unnoticed and
+  unhandled.<br>
+  But the user can change this behaviour to fit his needs, and select which
+  types of errors may raise exceptions using the following functions :</p>
+
+  <blockquote>
+    <pre>
+
+unsigned char exceptions(unsigned char newexcept); // query and set
+unsigned char exceptions() const;                  // just query
+
+</pre>
+  </blockquote>
+
+  <p>The user can compute the argument <i>newexcept</i> by combining the
+  following atoms using binary arithmetic :</p>
+
+  <ul>
+    <li><b>boost::io::bad_format_string_bit</b> selects errors due to
+    ill-formed format-strings.</li>
+
+    <li><b>boost::io::too_few_args_bit</b> selects errors due to asking for
+    the srting result before all arguments are passed.</li>
+
+    <li><b>boost::io::too_many_args_bit</b> selects errors due to passing too
+    many arguments.</li>
+
+    <li><b>boost::io::out_of_range_bit</b> select errors due to out of range
+    index supplied by the user when calling <i>modify_item</i> or other
+    functions taking an item index (or an argument index)</li>
+
+    <li><b>boost::io::all_error_bits</b> selects all errors</li>
+
+    <li><b>boost::io::no_error_bits</b> selects no error.</li>
+  </ul>
+
+  <p>For instance, if you don't want Boost.format to detect bad number of
+  arguments, you can define a specific wrapper function for building format
+  objects with the right exceptions settings :</p>
+
+  <blockquote>
+    <pre>
+
+boost::format  my_fmt(const std::string &amp; f_string) {
+    using namespace boost::io;
+    format fmter(f_string);
+    fmter.exceptions( all_error_bits ^ ( too_many_args_bit | too_few_args_bit )  );
+    return fmter;
+}
+
+</pre>
+  </blockquote>It is then allowed to give more arguments than needed (they
+  are simply ignored) :
+
+  <blockquote>
+    <pre>
+
+cout &lt;&lt; my_fmt(" %1% %2% \n") % 1 % 2 % 3 % 4 % 5;
+
+</pre>
+  </blockquote>And if we ask for the result before all arguments are
+  supplied, the corresponding part of the result is simply empty
+
+  <blockquote>
+    <pre>
+
+cout &lt;&lt; my_fmt(" _%2%_ _%1%_ \n") % 1 ;
+// prints      " __ _1_ \n"
+
+</pre>
+  </blockquote><a name="performance" id="performance"></a>
+  <hr>
+
+  <h2>A Note about performance</h2>
+
+  <p>The performance of boost::format for formatting a few builtin type
+  arguments with reordering can be compared to that of Posix-printf, and of
+  the equivalent stream manual operations to give a measure of the overhead
+  incurred. The result may greatly depend on the compiler, standard library
+  implementation, and the precise choice of format-string and arguments.</p>
+
+  <p>Common stream implementations eventually call functions of the
+  printf family for the actual formatting of numbers.  In general, printf
+  will be noticeably faster than the direct stream operations due to the
+  reordering overhead (allocations to store the pieces of string, stream
+  initialisation at each item formatting, ..).  The direct stream operations
+  would be faster than boost::format - one can expect a ratio ranging from 2
+  to 5 or more.</p>
+
+  <p>When iterated formattings are a performance bottleneck, performance can
+  be slightly increased by parsing the format string into a format object,
+  and copying it at each formatting, in the following way:</p>
+
+  <blockquote>
+    <pre>
+    const boost::format fmter(fstring);
+    dest &lt;&lt; boost::format(fmter) % arg1 % arg2 % arg3 ;
+    </pre>
+  </blockquote>
+
+  <p>As an example of performance results, the author measured the time of
+  execution of iterated formattings with 4 different methods:</p>
+
+  <ol>
+    <li>posix printf</li>
+
+    <li>manual stream output (to a dummy <i>nullStream</i> stream sending the
+    bytes into oblivion)</li>
+
+    <li>boost::format copied from a const object as shown above</li>
+
+    <li>the straight boost::format usage</li>
+  </ol>
+
+  <p>the test was compiled with g++-3.3.3 and the following timings were
+  measured (in seconds, and ratios):</p>
+
+  <blockquote>
+    <pre>
+string     fstring="%3$0#6x %1$20.10E %2$g %3$0+5d \n";
+double     arg1=45.23;
+double     arg2=12.34;
+int        arg3=23;
+
+- release mode :
+printf                 : 2.13
+nullStream             : 3.43,  = 1.61033 * printf
+boost::format copied   : 6.77,  = 3.1784  * printf ,  = 1.97376 * nullStream
+boost::format straight :10.67,  = 5.00939 * printf ,  = 3.11079 * nullStream
+
+- debug mode :
+printf                 : 2.12
+nullStream             : 3.69,  = 1.74057 * printf
+boost::format copied   :10.02,  = 4.72642 * printf ,  = 2.71545 * nullStream
+boost::format straight :17.03,  = 8.03302 * printf ,  = 4.61518 * nullStream
+</pre>
+  </blockquote><a name="extract" id="extract"></a>
+  <hr>
+
+  <h2>Class Interface Extract</h2>
+
+  <blockquote>
+    <pre>
+namespace boost {
+
+template&lt;class charT, class Traits=std::char_traits&lt;charT&gt; &gt; 
+class basic_format 
+{
+public:
+  typedef std::basic_string&lt;charT, Traits&gt; string_type;
+  typedef typename string_type::size_type     size_type;
+  basic_format(const charT* str);
+  basic_format(const charT* str, const std::locale &amp; loc);
+  basic_format(const string_type&amp; s);
+  basic_format(const string_type&amp; s, const std::locale &amp; loc);
+  basic_format&amp; operator= (const basic_format&amp; x);
+
+  void clear(); // reset buffers
+  basic_format&amp; parse(const string_type&amp;); // clears and parse a new format string
+
+  string_type str() const;
+  size_type size() const;
+
+  // pass arguments through those operators :
+  template&lt;class T&gt;  basic_format&amp;   operator%(T&amp; x);  
+  template&lt;class T&gt;  basic_format&amp;   operator%(const T&amp; x);
+
+  // dump buffers to ostream :
+  friend std::basic_ostream&lt;charT, Traits&gt;&amp; 
+  operator&lt;&lt; &lt;&gt; ( std::basic_ostream&lt;charT, Traits&gt;&amp; , basic_format&amp; ); 
+
+   // Choosing which errors will throw exceptions :
+   unsigned char exceptions() const;
+   unsigned char exceptions(unsigned char newexcept);
+
+// ............  this is just an extract .......
+}; // basic_format
+
+typedef basic_format&lt;char &gt;          format;
+typedef basic_format&lt;wchar_t &gt;      wformat;
+
+
+// free function for ease of use :
+template&lt;class charT, class Traits&gt; 
+std::basic_string&lt;charT,Traits&gt;  str(const basic_format&lt;charT,Traits&gt;&amp; f) {
+      return f.str();
+}
+
+
+} // namespace boost
+</pre>
+  </blockquote>
+  <hr>
+  <a name="rationale" id="rationale"></a>
+
+  <h2>Rationale</h2>
+
+  <p>This class's goal is to bring a better, C++, type-safe and
+  type-extendable <i>printf</i> equivalent to be used with
+  streams.</p>Precisely, <b>format</b> was designed to provide the following
+  features :
+
+  <ul>
+    <li>support positional arguments (required for internationalisation)</li>
+
+    <li>accept an unlimited number of arguments.</li>
+
+    <li>make formatting commands visually natural.</li>
+
+    <li>support the use of manipulators to modify the display of an argument.
+    in addition to the format-string syntax.</li>
+
+    <li>accept any types of variables, by relying on streams for the actual
+    conversion to string. This specifically concerns user-defined types, for
+    which the formatting options effects should be intuitively natural.</li>
+
+    <li>provide printf-compatibility, as much as it makes sense in a
+    type-safe and type-extendable context.</li>
+  </ul>
+
+  <p>In the process of the design, many issues were faced, and some choices
+  were made, that might not be intuitively right. But in each case they were
+  taken for <a href="choices.html">some reasons</a>.</p>
+  <hr>
+
+  <h2>Credits</h2>
+
+  <p>The author of Boost format is Samuel Krempp. &nbsp; He used ideas from
+  R&uuml;diger Loos' format.hpp and Karl Nelson's formatting classes.</p>
+  <hr>
+
+  <p><a href="http://validator.w3.org/check?uri=referer"><img border="0" src=
+  "../../../doc/images/valid-html401.png" alt="Valid HTML 4.01 Transitional"
+  height="31" width="88"></a></p>
+
+  <p>Revised 
+  <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->23 October, 2017<!--webbot bot="Timestamp" endspan i-checksum="38510" --></p>
+
+  <p><i>Copyright &copy; 2002 Samuel Krempp</i></p>
+
+  <p><i>Distributed under the Boost Software License, Version 1.0. (See
+  accompanying file <a href="../../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or
+  copy at <a href=
+  "http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>)</i></p>
+</body>
+</html>
diff --git a/example/Jamfile.v2 b/example/Jamfile.v2
new file mode 100644
index 0000000..6029e89
--- /dev/null
+++ b/example/Jamfile.v2
@@ -0,0 +1,16 @@
+#  Boost.Format Library example Jamfile
+#
+#  Copyright (c) 2003 Samuel Krempp
+#
+#  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)
+
+import testing ;
+
+test-suite "format-examples"
+   :    [ run sample_advanced.cpp ]
+        [ run sample_formats.cpp ]
+        [ run sample_new_features.cpp ]
+        [ run sample_userType.cpp ]
+   ;
+
diff --git a/example/sample_advanced.cpp b/example/sample_advanced.cpp
new file mode 100644
index 0000000..049bf6d
--- /dev/null
+++ b/example/sample_advanced.cpp
@@ -0,0 +1,156 @@
+// ----------------------------------------------------------------------------
+// sample_advanced.cc :  examples of adanced usage of format 
+// ----------------------------------------------------------------------------
+
+//  Copyright Samuel Krempp 2003. 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)
+
+//  See http://www.boost.org/libs/format for library home page
+
+// ----------------------------------------------------------------------------
+
+#include <iostream>
+#include <iomanip>
+
+#include "boost/format.hpp"
+
+
+namespace MyNS_ForOutput {
+  using std::cout; using std::cerr;
+  using std::string;
+  using std::endl; using std::flush;
+
+  using boost::format;
+  using boost::io::group;
+}
+
+namespace MyNS_Manips {
+  using std::setfill;
+  using std::setw;
+  using std::hex ;
+  using std::dec ;
+  using std::showbase ;
+  using std::left ;
+  using std::right ;
+  using std::internal ;
+}
+
+int main(){
+    using namespace MyNS_ForOutput;
+    using namespace MyNS_Manips;
+
+    std::string s;
+
+    //------------------------------------------------------------------------
+    // storing the parsed format-string in a 'formatter' : 
+    // format objects are regular objects that can be copied, assigned, 
+    // fed arguments, dumped to a stream, re-fed arguments, etc... 
+    // So users can use them the way they like.
+
+    format fmter("%1% %2% %3% %1% \n");
+    fmter % 10 % 20 % 30; 
+    cout  << fmter;
+    //          prints  "10 20 30 10 \n"
+    
+    // note that once the fmter got all its arguments, 
+    // the formatted string stays available  (until next call to '%')
+    //    The result is  available via function str() or stream's << :
+    cout << fmter; 
+    //          prints the same string again.
+
+
+    // once you call operator% again, arguments are cleared inside the object
+    // and it is an error to ask for the conversion string before feeding all arguments :
+    fmter % 1001;
+    try  { cout << fmter;   }
+    catch (boost::io::too_few_args& exc) { 
+      cout <<  exc.what() << "***Dont worry, that was planned\n";
+    }
+
+    // we just need to feed the last two arguments, and it will be ready for output again :
+    cout << fmter % 1002 % 1003;
+    //          prints  "1001 1002 1003 1001 \n"
+
+    cout  << fmter % 10 % 1 % 2;
+    //          prints  "10 1 2 10 \n"
+
+
+
+    //---------------------------------------------------------------
+    // using format objects 
+
+    // modify the formatting options for a given directive :
+    fmter = format("%1% %2% %3% %2% %1% \n");
+    fmter.modify_item(4, group(setfill('_'), hex, showbase, setw(5)) );
+    cout << fmter % 1 % 2 % 3;
+    //          prints  "1 2 3 __0x2 1 \n"
+    
+    // bind one of the argumets :
+    fmter.bind_arg(1, 18);
+    cout << fmter % group(hex, showbase, 20) % 30;  // %2 is 20, and 20 == 0x14
+    //          prints  "18 0x14 30  _0x14 18 \n"
+    
+    
+    fmter.modify_item(4, setw(0)); // cancels previous width-5
+    fmter.bind_arg(1, 77); // replace 18 with 77 for first argument.
+    cout << fmter % 10 % 20;
+    //          prints  "77 10 20 0xa 77 \n"
+
+    try  
+    { 
+      cout << fmter % 6 % 7 % 8;   // Aye ! too many args, because arg1 is bound already
+    }
+    catch (boost::io::too_many_args& exc) 
+    { 
+      cout <<  exc.what() << "***Dont worry, that was planned\n";
+    }
+
+    // clear regular arguments, but not bound arguments :
+    fmter.clear();
+    cout << fmter % 2 % 3;
+    //          prints "77 2 3 0x2 77 \n"
+
+    // clear_binds() clears both regular AND bound arguments :
+    fmter.clear_binds(); 
+    cout << fmter % 1 % 2 % 3;
+    //          prints  "1 2 3 0x2 1 \n"
+    
+ 
+    // setting desired exceptions :
+    fmter.exceptions( boost::io::all_error_bits ^( boost::io::too_many_args_bit ) );
+    cout << fmter % 1 % 2 % 3 % 4 % 5 % 6 ;
+
+
+   // -----------------------------------------------------------
+    // misc:
+
+    // unsupported printf directives %n and asterisk-fields are purely ignored.
+    // do *NOT* provide an argument for them, it is an error.
+    cout << format("|%5d| %n") % 7 << endl;
+    //          prints  "|    7| "
+    cout << format("|%*.*d|")  % 7 << endl;
+    //          prints "|7|"
+
+
+    // truncations of strings :
+    cout << format("%|.2s| %|8c|.\n") % "root" % "user";
+    //          prints  "ro        u.\n"
+
+
+    // manipulators conflicting with format-string : manipulators win.
+    cout << format("%2s")  % group(setfill('0'), setw(6), 1) << endl;
+    //          prints  "000001"
+    cout << format("%2$5s %1% %2$3s\n")  % 1    % group(setfill('X'), setw(4), 2) ;
+    //          prints  "XXX2 1 XXX2\n"  
+    //          width is 4, as set by manip, not the format-string.
+    
+    // nesting :
+    cout << format("%2$014x [%1%] %2$05s\n") % (format("%05s / %s") % -18 % 7)
+                                             % group(showbase, -100);
+    //          prints   "0x0000ffffff9c [-0018 / 7] -0100\n"
+
+
+    cout << "\n\nEverything went OK, exiting. \n";
+    return 0;
+}
diff --git a/example/sample_formats.cpp b/example/sample_formats.cpp
new file mode 100644
index 0000000..b1b6df9
--- /dev/null
+++ b/example/sample_formats.cpp
@@ -0,0 +1,112 @@
+// ----------------------------------------------------------------------------
+// sample_formats.cpp :  example of basic usage of format
+// ----------------------------------------------------------------------------
+
+//  Copyright Samuel Krempp 2003. 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)
+
+//  See http://www.boost.org/libs/format for library home page
+// ----------------------------------------------------------------------------
+
+#include <iostream>
+#include <iomanip>
+#include <cassert>
+
+#include "boost/format.hpp"
+
+// 2 custom namespaces, to bring in a few useful names :
+
+namespace MyNS_ForOutput {
+  using std::cout; using std::cerr;
+  using std::string;
+  using std::endl; using std::flush;
+
+  using boost::format;
+  using boost::io::group;
+}
+
+namespace MyNS_Manips {
+  using std::setfill;
+  using std::setw;
+  using std::hex ;
+  using std::dec ;
+// gcc-2.95 doesnt define the next ones
+//  using std::showbase ;
+//  using std::left ;
+//  using std::right ;
+//  using std::internal ;
+}
+
+int main(){
+    using namespace MyNS_ForOutput;
+    using namespace MyNS_Manips;
+
+    std::cout << format("%|1$1| %|2$3|") % "Hello" % 3 << std::endl;
+
+    // Reordering :
+    cout << format("%1% %2% %3% %2% %1% \n") % "o" % "oo" % "O"; // 'simple' style.
+    //          prints  "o oo O oo o \n"
+    cout << format("(x,y) = (%1$+5d,%2$+5d) \n") % -23 % 35;     // Posix-Printf style
+
+
+    // No reordering :
+    cout << format("writing %s,  x=%s : %d-th step \n") % "toto" % 40.23 % 50; 
+    //          prints  "writing toto,  x=40.23 : 50-th step \n"
+
+    cout << format("(x,y) = (%+5d,%+5d) \n") % -23 % 35;
+    cout << format("(x,y) = (%|+5|,%|+5|) \n") % -23 % 35;
+    cout << format("(x,y) = (%|1$+5|,%|2$+5|) \n") % -23 % 35;
+    //   all those are the same,  it prints  "(x,y) = (  -23,  +35) \n"
+
+
+
+    // Using manipulators, via 'group' :
+    cout << format("%2% %1% %2%\n")  % 1   % group(setfill('X'), hex, setw(4), 16+3) ;
+    // prints "XX13 1 XX13\n"
+
+
+    // printf directives's type-flag can be used to pass formatting options :
+    cout <<  format("_%1$4d_ is : _%1$#4x_, _%1$#4o_, and _%1$s_ by default\n")  % 18;
+    //          prints  "_  18_ is : _0x12_, _ 022_, and _18_ by default\n"
+
+    // Taking the string value :
+    std::string s;
+    s= str( format(" %d %d ") % 11 % 22 );
+    assert( s == " 11 22 ");
+
+
+    // -----------------------------------------------
+    //  %% prints '%'
+
+    cout << format("%%##%#x ") % 20 << endl;
+    //          prints  "%##0x14 "
+ 
+
+    // -----------------------------------------------
+    //    Enforcing the right number of arguments 
+
+    // Too much arguments will throw an exception when feeding the unwanted argument :
+    try {
+      format(" %1% %1% ") % 101 % 102;
+      // the format-string refers to ONE argument, twice. not 2 arguments.
+      // thus giving 2 arguments is an error
+    }
+    catch (boost::io::too_many_args& exc) { 
+      cerr <<  exc.what() << "\n\t\t***Dont worry, that was planned\n";
+    }
+
+    
+    // Too few arguments when requesting the result will also throw an exception :
+    try {
+      cerr << format(" %|3$| ") % 101; 
+      // even if %1$ and %2$ are not used, you should have given 3 arguments
+    }
+    catch (boost::io::too_few_args& exc) { 
+      cerr <<  exc.what() << "\n\t\t***Dont worry, that was planned\n";
+    }
+
+    
+    cerr << "\n\nEverything went OK, exiting. \n";
+    return 0;
+}
diff --git a/example/sample_new_features.cpp b/example/sample_new_features.cpp
new file mode 100644
index 0000000..53fffef
--- /dev/null
+++ b/example/sample_new_features.cpp
@@ -0,0 +1,68 @@
+// ----------------------------------------------------------------------------
+// sample_new_features.cpp : demonstrate features added to printf's syntax
+// ----------------------------------------------------------------------------
+
+//  Copyright Samuel Krempp 2003. 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)
+
+//  See http://www.boost.org/libs/format for library home page
+
+// ----------------------------------------------------------------------------
+
+#include <iostream>
+#include <iomanip>
+
+#include "boost/format.hpp"
+
+int main(){
+    using namespace std;
+    using boost::format;
+    using boost::io::group;
+
+    // ------------------------------------------------------------------------
+    // Simple style of reordering :
+    cout << format("%1% %2% %3% %2% %1% \n") % "o" % "oo" % "O";
+    //          prints  "o oo O oo o \n"
+
+
+    // ------------------------------------------------------------------------
+    // Centered alignment : flag '='
+    cout << format("_%|=6|_") % 1 << endl;
+    //          prints "_   1  _"  :  3 spaces are  padded before, and 2 after.
+
+
+
+    // ------------------------------------------------------------------------
+    // Tabulations :   "%|Nt|"  => tabulation of N spaces.
+    //                 "%|NTf|" => tabulation of N times the character <f>.
+    //  are useful when printing lines with several fields whose width can vary a lot
+    //    but we'd like to print some fields at the same place when possible :
+    vector<string>  names(1, "Marc-François Michel"), 
+      surname(1,"Durand"), 
+      tel(1, "+33 (0) 123 456 789");
+
+    names.push_back("Jean"); 
+    surname.push_back("de Lattre de Tassigny");
+    tel.push_back("+33 (0) 987 654 321");
+
+    for(unsigned int i=0; i<names.size(); ++i)
+      cout << format("%1%, %2%, %|40t|%3%\n") % names[i] % surname[i] % tel[i];
+
+    /* prints :
+
+       
+    Marc-François Michel, Durand,       +33 (0) 123 456 789
+    Jean, de Lattre de Tassigny,        +33 (0) 987 654 321
+    
+    
+     the same using width on each field lead to unnecessary too long lines,
+     while 'Tabulations' insure a lower bound on the *sum* of widths,
+     and that's often what we really want.
+    */
+
+
+
+    cerr << "\n\nEverything went OK, exiting. \n";
+    return 0;
+}
diff --git a/example/sample_userType.cpp b/example/sample_userType.cpp
new file mode 100644
index 0000000..f35b926
--- /dev/null
+++ b/example/sample_userType.cpp
@@ -0,0 +1,180 @@
+// ----------------------------------------------------------------------------
+// sample_userType.cc :  example usage of format with a user-defined type
+// ----------------------------------------------------------------------------
+
+//  Copyright Samuel Krempp 2003. 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)
+
+//  See http://www.boost.org/libs/format for library home page
+
+// ----------------------------------------------------------------------------
+
+
+#include <iostream>
+#include <iomanip>
+#include "boost/format.hpp"
+#include <boost/cast.hpp>
+
+#if !(BOOST_WORKAROUND(__GNUC__, < 3) && defined(__STL_CONFIG_H) ) 
+  // not for broken gcc stdlib
+#include <boost/io/ios_state.hpp>
+
+#else
+// not as complete, but compatible with gcc-2.95 :
+
+void copyfmt(ios& left, const ios& right) {
+    left.fill(right.fill());
+    left.flags(right.flags() );
+    left.exceptions(right.exceptions());
+    left.width(right.width());
+    left.precision(right.precision());
+}
+
+namespace boost { namespace io {
+class ios_all_saver {
+    std::basic_ios<char>  ios_;
+    std::ios & target_r;
+public:
+    ios_all_saver(std::ios& right) : ios_(0), target_r(right) {
+        copyfmt(ios_, right);
+    }
+    ~ios_all_saver() {
+        copyfmt(target_r, ios_);
+    }
+};
+
+} } // N.S. boost::io
+
+
+// define showpos and noshowpos : 
+class ShowPos {
+public:
+    bool showpos_;
+    ShowPos(bool v) : showpos_(v) {}
+};
+std::ostream& operator<<(std::ostream& os, const ShowPos& x) { 
+    if(x.showpos_) 
+        os.setf(ios_base:: showpos);
+    else
+        os.unsetf(ios_base:: showpos);
+    return os; 
+}
+ShowPos noshowpos(false);
+ShowPos showpos(true);
+
+#endif // -end gcc-2.95 workarounds
+
+
+
+//---------------------------------------------------------------------------//
+//  *** an exemple of UDT : a Rational class ****
+class Rational {
+public:
+  Rational(int n, unsigned int d) : n_(n), d_(d) {}
+  Rational(int n, int d);    // convert denominator to unsigned
+  friend std::ostream& operator<<(std::ostream&, const Rational&);
+private:
+  int n_;               // numerator
+  unsigned int d_;      // denominator
+};
+
+Rational::Rational(int n, int d) : n_(n) 
+{
+  if(d < 0) { n_ = -n_; d=-d; } // make the denominator always non-negative.
+    d_ = static_cast<unsigned int>(d);
+}
+
+std::ostream& operator<<(std::ostream& os, const Rational& r) {
+  using namespace std;
+  streamsize  n, s1, s2, s3;
+  streamsize w = os.width(0); // width has to be zeroed before saving state.
+//  boost::io::ios_all_saver  bia_saver (os); 
+ 
+  boost::io::basic_oaltstringstream<char> oss;
+  oss.copyfmt(os );
+  oss << r.n_; 
+  s1 = oss.size();
+  oss << "/" << noshowpos; // a rational number needs only one sign !
+  s2 = oss.size();
+  oss << r.d_ ;
+  s3 = oss.size();
+
+  n = w - s3;
+  if(n <= 0) {
+      os.write(oss.begin(), oss.size());
+  }
+  else if(os.flags() & std::ios_base::internal) {
+    std::streamsize n1 = w/2, n2 = w - n1,  t;
+    t = (s3-s1) - n2; // is 2d part '/nnn' bigger than 1/2 w ?
+    if(t > 0)  {
+      n1 = w -(s3-s1); // put all paddings on first part.
+      n2 = 0; // minimal width (s3-s2)
+    } 
+    else {
+      n2 -= s2-s1; // adjust for '/',   n2 is still w/2.
+    }
+    os << setw(n1) << r.n_ << "/" << noshowpos << setw(n2) << r.d_;
+  }
+  else {
+    if(! (os.flags() & std::ios_base::left)) { 
+        // -> right align. (right bit is set, or no bit is set)
+        os << string(boost::numeric_cast<std::string::size_type>(n), ' ');
+    }
+    os.write(oss.begin(), s3);
+    if( os.flags() & std::ios_base::left ) {
+      os << string(boost::numeric_cast<std::string::size_type>(n), ' ');
+    }
+  }
+
+  return os;
+}
+
+
+
+int main(){
+    using namespace std;
+    using boost::format;
+    using boost::io::group; 
+    using boost::io::str;
+    string s;
+
+    Rational  r(16, 9);
+
+    cout << "bonjour ! " << endl;
+    // "bonjour !"
+
+    cout << r << endl;
+    // "16/9" 
+
+    cout << showpos << r << ", " << 5 << endl;
+    // "+16/9, +5"
+
+    cout << format("%02d : [%0+9d] \n") % 1 % r ;
+    // "01 : [+016 / 0009]"
+
+    cout << format("%02d : [%_+9d] \n") % 2 % Rational(9,160);
+    // "02 : [+9 / 160]"
+
+    cout << format("%02d : [%_+9d] \n") % 3 % r;
+    // "03 : [+16 / 9]"
+		
+    cout << format("%02d : [%_9d] \n") % 4 % Rational(8,1234);
+    // "04 : [8 / 1234]"
+    
+    cout << format("%02d : [%_9d] \n") % 5 % Rational(1234,8);
+    // "05 : [1234 / 8]"
+
+    cout << format("%02d : [%09d] \n") % 6 % Rational(8,1234);
+    // "06 : [0008 / 1234]"
+
+    cout << format("%02d : [%0+9d] \n") % 7 % Rational(1234,8);
+    // "07 : [+1234 / 008]"
+
+    cout << format("%02d : [%0+9d] \n") % 8 % Rational(7,12345);
+    // "08 : [+07 / 12345]"
+
+
+    cerr << "\n\nEverything went OK, exiting. \n";
+    return 0;
+}
diff --git a/include/boost/format.hpp b/include/boost/format.hpp
new file mode 100644
index 0000000..73464a8
--- /dev/null
+++ b/include/boost/format.hpp
@@ -0,0 +1,59 @@
+// ----------------------------------------------------------------------------
+// format.hpp :  primary header
+// ----------------------------------------------------------------------------
+
+//  Copyright Samuel Krempp 2003. 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)
+
+//  See http://www.boost.org/libs/format for library home page
+
+
+// ----------------------------------------------------------------------------
+
+#ifndef BOOST_FORMAT_HPP
+#define BOOST_FORMAT_HPP
+
+#include <vector>
+#include <string>
+#include <boost/detail/workaround.hpp>
+#include <boost/config.hpp>
+
+#ifndef BOOST_NO_STD_LOCALE
+#include <locale>
+#endif
+
+// ***   Compatibility framework
+#include <boost/format/detail/compat_workarounds.hpp>
+
+#ifdef BOOST_NO_LOCALE_ISIDIGIT
+#include <cctype>  // we'll use the non-locale  <cctype>'s std::isdigit(int)
+#endif
+
+// ****  Forward declarations ----------------------------------
+#include <boost/format/format_fwd.hpp>     // basic_format<Ch,Tr>, and other frontends
+#include <boost/format/internals_fwd.hpp>  // misc forward declarations for internal use
+
+// ****  Auxiliary structs (stream_format_state<Ch,Tr> , and format_item<Ch,Tr> )
+#include <boost/format/internals.hpp>    
+
+// ****  Format  class  interface --------------------------------
+#include <boost/format/format_class.hpp>
+
+// **** Exceptions -----------------------------------------------
+#include <boost/format/exceptions.hpp>
+
+// **** Implementation -------------------------------------------
+#include <boost/format/format_implementation.hpp>   // member functions
+#include <boost/format/group.hpp>                   // class for grouping arguments
+#include <boost/format/feed_args.hpp>               // argument-feeding functions
+#include <boost/format/parsing.hpp>                 // format-string parsing (member-)functions
+
+// **** Implementation of the free functions ----------------------
+#include <boost/format/free_funcs.hpp>
+
+
+// *** Undefine 'local' macros :
+#include <boost/format/detail/unset_macros.hpp>
+
+#endif // BOOST_FORMAT_HPP
diff --git a/include/boost/format/alt_sstream.hpp b/include/boost/format/alt_sstream.hpp
new file mode 100644
index 0000000..138e175
--- /dev/null
+++ b/include/boost/format/alt_sstream.hpp
@@ -0,0 +1,177 @@
+// ----------------------------------------------------------------------------
+//  alt_sstream.hpp : alternative stringstream 
+// ----------------------------------------------------------------------------
+
+//  Copyright Samuel Krempp 2003. 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)
+
+//  See http://www.boost.org/libs/format for library home page
+
+// ----------------------------------------------------------------------------
+
+
+
+#ifndef BOOST_SK_ALT_SSTREAM_HPP
+#define BOOST_SK_ALT_SSTREAM_HPP
+
+#include <string>
+#include <boost/format/detail/compat_workarounds.hpp>
+#include <boost/utility/base_from_member.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/config.hpp>
+#include <boost/assert.hpp>
+
+namespace boost {
+    namespace io {
+
+        template<class Ch, class Tr=::std::char_traits<Ch>, 
+                 class Alloc=::std::allocator<Ch> >
+        class basic_altstringbuf;
+
+        template<class Ch, class Tr =::std::char_traits<Ch>, 
+                 class Alloc=::std::allocator<Ch> >
+        class basic_oaltstringstream;
+
+
+        template<class Ch, class Tr, class Alloc>
+        class basic_altstringbuf 
+            : public ::std::basic_streambuf<Ch, Tr>
+        {
+            typedef ::std::basic_streambuf<Ch, Tr>  streambuf_t;
+            typedef typename CompatAlloc<Alloc>::compatible_type compat_allocator_type;
+            typedef typename CompatTraits<Tr>::compatible_type   compat_traits_type;
+        public:
+            typedef Ch     char_type;
+            typedef Tr     traits_type;
+            typedef typename compat_traits_type::int_type     int_type;
+            typedef typename compat_traits_type::pos_type     pos_type;
+            typedef typename compat_traits_type::off_type     off_type;
+            typedef Alloc                     allocator_type;
+            typedef ::std::basic_string<Ch, Tr, Alloc> string_type;
+            typedef typename string_type::size_type    size_type;
+
+            typedef ::std::streamsize streamsize;
+
+
+            explicit basic_altstringbuf(std::ios_base::openmode mode
+                                        = std::ios_base::in | std::ios_base::out)
+                : putend_(NULL), is_allocated_(false), mode_(mode) 
+                {}
+            explicit basic_altstringbuf(const string_type& s,
+                                        ::std::ios_base::openmode mode
+                                        = ::std::ios_base::in | ::std::ios_base::out)
+                : putend_(NULL), is_allocated_(false), mode_(mode) 
+                { dealloc(); str(s); }
+            virtual ~basic_altstringbuf() BOOST_NOEXCEPT_OR_NOTHROW
+                { dealloc(); }
+            using streambuf_t::pbase;
+            using streambuf_t::pptr;
+            using streambuf_t::epptr;
+            using streambuf_t::eback;
+            using streambuf_t::gptr;
+            using streambuf_t::egptr;
+    
+            void clear_buffer();
+            void str(const string_type& s);
+
+            // 0-copy access :
+            Ch * begin() const; 
+            size_type size() const;
+            size_type cur_size() const; // stop at current pointer
+            Ch * pend() const // the highest position reached by pptr() since creation
+                { return ((putend_ < pptr()) ? pptr() : putend_); }
+            size_type pcount() const 
+                { return static_cast<size_type>( pptr() - pbase()) ;}
+
+            // copy buffer to string :
+            string_type str() const 
+                { return string_type(begin(), size()); }
+            string_type cur_str() const 
+                { return string_type(begin(), cur_size()); }
+        protected:
+            explicit basic_altstringbuf (basic_altstringbuf * s,
+                                         ::std::ios_base::openmode mode 
+                                         = ::std::ios_base::in | ::std::ios_base::out)
+                : putend_(NULL), is_allocated_(false), mode_(mode) 
+                { dealloc(); str(s); }
+
+            virtual pos_type seekoff(off_type off, ::std::ios_base::seekdir way, 
+                                     ::std::ios_base::openmode which 
+                                     = ::std::ios_base::in | ::std::ios_base::out);
+            virtual pos_type seekpos (pos_type pos, 
+                                      ::std::ios_base::openmode which 
+                                      = ::std::ios_base::in | ::std::ios_base::out);
+            virtual int_type underflow();
+            virtual int_type pbackfail(int_type meta = compat_traits_type::eof());
+            virtual int_type overflow(int_type meta = compat_traits_type::eof());
+            void dealloc();
+        private:
+            enum { alloc_min = 256}; // minimum size of allocations
+
+            Ch *putend_;  // remembers (over seeks) the highest value of pptr()
+            bool is_allocated_;
+            ::std::ios_base::openmode mode_;
+            compat_allocator_type alloc_;  // the allocator object
+        };
+
+
+// ---   class basic_oaltstringstream ----------------------------------------
+        template <class Ch, class Tr, class Alloc>
+        class basic_oaltstringstream 
+            : private base_from_member< shared_ptr< basic_altstringbuf< Ch, Tr, Alloc> > >,
+              public ::std::basic_ostream<Ch, Tr>
+        {
+            class No_Op { 
+                // used as no-op deleter for (not-owner) shared_pointers
+            public: 
+                template<class T>
+                const T & operator()(const T & arg) { return arg; }
+            };
+            typedef ::std::basic_ostream<Ch, Tr> stream_t;
+            typedef boost::base_from_member<boost::shared_ptr<
+                basic_altstringbuf<Ch,Tr, Alloc> > > 
+                pbase_type;
+            typedef ::std::basic_string<Ch, Tr, Alloc>  string_type;
+            typedef typename string_type::size_type     size_type;
+            typedef basic_altstringbuf<Ch, Tr, Alloc>   stringbuf_t;
+        public:
+            typedef Alloc  allocator_type;
+            basic_oaltstringstream() 
+                : pbase_type(new stringbuf_t), stream_t(pbase_type::member.get())
+                { }
+            basic_oaltstringstream(::boost::shared_ptr<stringbuf_t> buf) 
+                : pbase_type(buf), stream_t(pbase_type::member.get())
+                { }
+            basic_oaltstringstream(stringbuf_t * buf) 
+                : pbase_type(buf, No_Op() ), stream_t(pbase_type::member.get())
+                { }
+            stringbuf_t * rdbuf() const 
+                { return pbase_type::member.get(); }
+            void clear_buffer() 
+                { rdbuf()->clear_buffer(); }
+
+            // 0-copy access :
+            Ch * begin() const 
+                { return rdbuf()->begin(); }
+            size_type size() const 
+                { return rdbuf()->size(); }
+            size_type cur_size() const // stops at current position
+                { return rdbuf()->cur_size(); }
+
+            // copy buffer to string :
+            string_type str()     const   // [pbase, epptr[
+                { return rdbuf()->str(); } 
+            string_type cur_str() const   // [pbase, pptr[
+                { return rdbuf()->cur_str(); }
+            void str(const string_type& s) 
+                { rdbuf()->str(s); }
+        };
+
+    } // N.S. io
+} // N.S. boost
+
+#include <boost/format/alt_sstream_impl.hpp>
+
+#endif // include guard
+
diff --git a/include/boost/format/alt_sstream_impl.hpp b/include/boost/format/alt_sstream_impl.hpp
new file mode 100644
index 0000000..998f8b2
--- /dev/null
+++ b/include/boost/format/alt_sstream_impl.hpp
@@ -0,0 +1,313 @@
+// ----------------------------------------------------------------------------
+//  alt_sstream_impl.hpp : alternative stringstream, templates implementation 
+// ----------------------------------------------------------------------------
+
+//  Copyright Samuel Krempp 2003. 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)
+
+//  See http://www.boost.org/libs/format for library home page
+
+// ----------------------------------------------------------------------------
+
+#ifndef BOOST_SK_ALT_SSTREAM_IMPL_HPP
+#define BOOST_SK_ALT_SSTREAM_IMPL_HPP
+
+namespace boost {
+    namespace io {
+// --- Implementation  ------------------------------------------------------//
+
+        template<class Ch, class Tr, class Alloc>
+        void basic_altstringbuf<Ch, Tr, Alloc>:: 
+        clear_buffer () {
+            const Ch * p = pptr();
+            const Ch * b = pbase();
+            if(p != NULL && p != b) {
+                seekpos(0, ::std::ios_base::out); 
+            }
+            p = gptr();
+            b = eback();
+            if(p != NULL && p != b) {
+                seekpos(0, ::std::ios_base::in); 
+            }
+        }
+
+        template<class Ch, class Tr, class Alloc>
+        void basic_altstringbuf<Ch, Tr, Alloc>:: 
+        str (const string_type& s) {
+            size_type sz=s.size();
+            if(sz != 0 && mode_ & (::std::ios_base::in | ::std::ios_base::out) ) {
+#ifdef _RWSTD_NO_CLASS_PARTIAL_SPEC
+                void *vd_ptr = alloc_.allocate(sz, is_allocated_? eback() : 0);
+                Ch *new_ptr = static_cast<Ch *>(vd_ptr);
+#else
+                Ch *new_ptr = alloc_.allocate(sz, is_allocated_? eback() : 0);
+#endif
+                // if this didnt throw, we're safe, update the buffer
+                dealloc();
+                sz = s.copy(new_ptr, sz);
+                putend_ = new_ptr + sz;
+                if(mode_ & ::std::ios_base::in)
+                    streambuf_t::setg(new_ptr, new_ptr, new_ptr + sz);
+                if(mode_ & ::std::ios_base::out) {
+                    streambuf_t::setp(new_ptr, new_ptr + sz);
+                    if(mode_ & (::std::ios_base::app | ::std::ios_base::ate))
+                        streambuf_t::pbump(static_cast<int>(sz));
+                    if(gptr() == NULL)
+                        streambuf_t::setg(new_ptr, NULL, new_ptr);
+                }
+                is_allocated_ = true;
+            }
+            else 
+                dealloc();
+        }
+        template<class Ch, class Tr, class Alloc>
+        Ch*   basic_altstringbuf<Ch, Tr, Alloc>:: 
+        begin () const {
+            if(mode_ & ::std::ios_base::out && pptr() != NULL)
+                return pbase();
+            else if(mode_ & ::std::ios_base::in && gptr() != NULL)
+                return eback();
+            return NULL;
+        }
+
+        template<class Ch, class Tr, class Alloc>
+        typename std::basic_string<Ch,Tr,Alloc>::size_type
+        basic_altstringbuf<Ch, Tr, Alloc>:: 
+        size () const { 
+            if(mode_ & ::std::ios_base::out && pptr())
+                return static_cast<size_type>(pend() - pbase());
+            else if(mode_ & ::std::ios_base::in && gptr())
+                return static_cast<size_type>(egptr() - eback());
+            else 
+                return 0;
+        }
+
+        template<class Ch, class Tr, class Alloc>
+        typename std::basic_string<Ch,Tr,Alloc>::size_type
+        basic_altstringbuf<Ch, Tr, Alloc>:: 
+        cur_size () const { 
+            if(mode_ & ::std::ios_base::out && pptr())
+                return static_cast<streamsize>( pptr() - pbase());
+            else if(mode_ & ::std::ios_base::in && gptr())
+                return static_cast<streamsize>( gptr() - eback());
+            else 
+                return 0;
+        }
+
+        template<class Ch, class Tr, class Alloc>
+        typename basic_altstringbuf<Ch, Tr, Alloc>::pos_type  
+        basic_altstringbuf<Ch, Tr, Alloc>:: 
+        seekoff (off_type off, ::std::ios_base::seekdir way, ::std::ios_base::openmode which) {
+            if(pptr() != NULL && putend_ < pptr())
+                putend_ = pptr();
+            if(which & ::std::ios_base::in && gptr() != NULL) {
+                // get area
+                if(way == ::std::ios_base::end)
+                    off += static_cast<off_type>(putend_ - gptr());
+                else if(way == ::std::ios_base::beg)
+                    off += static_cast<off_type>(eback() - gptr());
+                else if(way != ::std::ios_base::cur || (which & ::std::ios_base::out) )
+                    // (altering in&out is only supported if way is beg or end, not cur)
+                    return pos_type(off_type(-1));
+                if(eback() <= off+gptr() && off+gptr() <= putend_ ) {
+                    // set gptr
+                    streambuf_t::gbump(static_cast<int>(off));
+                    if(which & ::std::ios_base::out && pptr() != NULL)
+                        // update pptr to match gptr
+                        streambuf_t::pbump(static_cast<int>(gptr()-pptr()));
+                }
+                else
+                    off = off_type(-1);
+            }
+            else if(which & ::std::ios_base::out && pptr() != NULL) {
+                // put area
+                if(way == ::std::ios_base::end)
+                    off += static_cast<off_type>(putend_ - pptr());
+                else if(way == ::std::ios_base::beg)
+                    off += static_cast<off_type>(pbase() - pptr());
+                else if(way != ::std::ios_base::beg)
+                    return pos_type(off_type(-1));                    
+                if(pbase() <= off+pptr() && off+pptr() <= putend_)
+                    // set pptr
+                    streambuf_t::pbump(static_cast<int>(off)); 
+                else
+                    off = off_type(-1);
+            }
+            else // neither in nor out
+                off = off_type(-1);
+            return (pos_type(off));
+        }
+        //- end seekoff(..)
+
+        
+        template<class Ch, class Tr, class Alloc>
+        typename basic_altstringbuf<Ch, Tr, Alloc>::pos_type 
+        basic_altstringbuf<Ch, Tr, Alloc>:: 
+        seekpos (pos_type pos, ::std::ios_base::openmode which) {
+            off_type off = off_type(pos); // operation guaranteed by fpos.operations table 127
+            if(pptr() != NULL && putend_ < pptr())
+                putend_ = pptr();
+            if(off != off_type(-1)) {
+                if(which & ::std::ios_base::in && gptr() != NULL) {
+                    // get area
+                    if(0 <= off && off <= putend_ - eback()) {
+                        streambuf_t::gbump(static_cast<int>(eback() - gptr() + off));
+                        if(which & ::std::ios_base::out && pptr() != NULL) {
+                            // update pptr to match gptr
+                            streambuf_t::pbump(static_cast<int>(gptr()-pptr()));
+                        }
+                    }
+                    else
+                        off = off_type(-1);
+                }
+                else if(which & ::std::ios_base::out && pptr() != NULL) {
+                    // put area
+                    if(0 <= off && off <= putend_ - eback())
+                        streambuf_t::pbump(static_cast<int>(eback() - pptr() + off));
+                    else
+                        off = off_type(-1);
+                }
+                else // neither in nor out
+                    off = off_type(-1);
+                return (pos_type(off));
+            }
+            else {
+                BOOST_ASSERT(0); // fpos.operations allows undefined-behaviour here
+                return pos_type(off_type(-1));
+            }
+        }
+        // -end seekpos(..)
+
+
+        template<class Ch, class Tr, class Alloc>
+        typename basic_altstringbuf<Ch, Tr, Alloc>::int_type
+        basic_altstringbuf<Ch, Tr, Alloc>:: 
+        underflow () {
+            if(gptr() == NULL) // no get area -> nothing to get.
+                return (compat_traits_type::eof()); 
+            else if(gptr() < egptr())  // ok, in buffer
+                return (compat_traits_type::to_int_type(*gptr())); 
+            else if(mode_ & ::std::ios_base::in && pptr() != NULL
+                    && (gptr() < pptr() || gptr() < putend_) )
+                {  // expand get area 
+                    if(putend_ < pptr()) 
+                        putend_ = pptr(); // remember pptr reached this far
+                    streambuf_t::setg(eback(), gptr(), putend_);
+                    return (compat_traits_type::to_int_type(*gptr()));
+                }
+            else // couldnt get anything. EOF.
+                return (compat_traits_type::eof());
+        }
+        // -end underflow(..)
+
+
+        template<class Ch, class Tr, class Alloc>
+        typename basic_altstringbuf<Ch, Tr, Alloc>::int_type 
+        basic_altstringbuf<Ch, Tr, Alloc>:: 
+        pbackfail (int_type meta) {
+            if(gptr() != NULL  &&  (eback() < gptr()) 
+               && (mode_ & (::std::ios_base::out)
+                   || compat_traits_type::eq_int_type(compat_traits_type::eof(), meta)
+                   || compat_traits_type::eq(compat_traits_type::to_char_type(meta), gptr()[-1]) ) ) { 
+                streambuf_t::gbump(-1); // back one character
+                if(!compat_traits_type::eq_int_type(compat_traits_type::eof(), meta))
+                    //  put-back meta into get area
+                    *gptr() = compat_traits_type::to_char_type(meta);
+                return (compat_traits_type::not_eof(meta));
+            }
+            else
+                return (compat_traits_type::eof());  // failed putback
+        }
+        // -end pbackfail(..)
+
+
+        template<class Ch, class Tr, class Alloc>
+        typename basic_altstringbuf<Ch, Tr, Alloc>::int_type 
+        basic_altstringbuf<Ch, Tr, Alloc>:: 
+        overflow (int_type meta) {
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4996)
+#endif
+            if(compat_traits_type::eq_int_type(compat_traits_type::eof(), meta))
+                return compat_traits_type::not_eof(meta); // nothing to do
+            else if(pptr() != NULL && pptr() < epptr()) {
+                streambuf_t::sputc(compat_traits_type::to_char_type(meta));
+                return meta;
+            }
+            else if(! (mode_ & ::std::ios_base::out)) 
+                // no write position, and cant make one
+                return compat_traits_type::eof(); 
+            else { // make a write position available
+                std::size_t prev_size = pptr() == NULL ? 0 : epptr() - eback();
+                std::size_t new_size = prev_size;
+                // exponential growth : size *= 1.5
+                std::size_t add_size = new_size / 2;
+                if(add_size < alloc_min)
+                    add_size = alloc_min;
+                Ch * newptr = NULL,  *oldptr = eback();
+
+                // make sure adding add_size wont overflow size_t
+                while (0 < add_size && ((std::numeric_limits<std::size_t>::max)()
+                                        - add_size < new_size) )
+                    add_size /= 2;
+                if(0 < add_size) {
+                    new_size += add_size;
+#ifdef _RWSTD_NO_CLASS_PARTIAL_SPEC
+                    void *vdptr = alloc_.allocate(new_size, is_allocated_? oldptr : 0);
+                    newptr = static_cast<Ch *>(vdptr);
+#else
+                    newptr = alloc_.allocate(new_size, is_allocated_? oldptr : 0);
+#endif
+                }
+
+                if(0 < prev_size)
+                    compat_traits_type::copy(newptr, oldptr, prev_size);
+                if(is_allocated_)
+                    alloc_.deallocate(oldptr, prev_size);
+                is_allocated_=true;
+
+                if(prev_size == 0) { // first allocation
+                    putend_ = newptr;
+                    streambuf_t::setp(newptr, newptr + new_size);
+                    if(mode_ & ::std::ios_base::in)
+                        streambuf_t::setg(newptr, newptr, newptr + 1);
+                    else
+                        streambuf_t::setg(newptr, 0, newptr);
+                }
+                else { // update pointers
+                    putend_ = putend_ - oldptr + newptr;
+                    int pptr_count = static_cast<int>(pptr()-pbase());
+                    int gptr_count = static_cast<int>(gptr()-eback());
+                    streambuf_t::setp(pbase() - oldptr + newptr, newptr + new_size);
+                    streambuf_t::pbump(pptr_count);
+                    if(mode_ & ::std::ios_base::in)
+                        streambuf_t::setg(newptr, newptr + gptr_count, pptr() + 1);
+                    else
+                        streambuf_t::setg(newptr, 0, newptr);
+                }
+                streambuf_t::sputc(compat_traits_type::to_char_type(meta));
+                return meta;
+            }
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+        }
+        // -end overflow(..)
+
+        template<class Ch, class Tr, class Alloc>
+        void basic_altstringbuf<Ch, Tr, Alloc>:: dealloc() {
+            if(is_allocated_)
+                alloc_.deallocate(eback(), (pptr() != NULL ? epptr() : egptr()) - eback());
+            is_allocated_ = false;
+            streambuf_t::setg(0, 0, 0);
+            streambuf_t::setp(0, 0);
+            putend_ = NULL;
+        }
+
+    }// N.S. io
+} // N.S. boost
+
+#endif // include guard
+
diff --git a/include/boost/format/detail/compat_workarounds.hpp b/include/boost/format/detail/compat_workarounds.hpp
new file mode 100644
index 0000000..8e51514
--- /dev/null
+++ b/include/boost/format/detail/compat_workarounds.hpp
@@ -0,0 +1,86 @@
+// ----------------------------------------------------------------------------
+//  compat_workarounds : general framework for non-conformance workarounds
+// ----------------------------------------------------------------------------
+
+//  Copyright Samuel Krempp 2003. 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)
+
+// see http://www.boost.org/libs/format for library home page
+
+// ----------------------------------------------------------------------------
+
+
+//  this file defines  wrapper classes to hide non-conforming 
+// std::char_traits<>  and std::allocator<> traits
+//  and Includes : config_macros.hpp (defines config macros
+//  and compiler-specific switches)
+
+// Non-conformant Std-libs fail to supply conformant traits (std::char_traits,
+//  std::allocator) and/or  the std::string doesnt support them.
+// We don't want to have hundreds of #ifdef workarounds, so we define 
+// replacement traits.
+// But both char_traits and allocator traits are visible in the interface, 
+// (inside the final string type),  thus we need to keep both 
+// the replacement type (typedefed to 'compatible_type') for real use,
+// and the original stdlib type (typedef to 'type_for_string') for interface
+//  visibility. This is what Compat* classes do (as well as be transparent 
+// when good allocator and char traits are present)
+
+#ifndef BOOST_FORMAT_COMPAT_WORKAROUNDS_HPP
+#define BOOST_FORMAT_COMPAT_WORKAROUNDS_HPP
+
+namespace boost {
+    namespace io {
+
+        // gcc-2.95 char traits (non-conformantly named string_char_traits) 
+        // lack several functions so we extend them in a replacement class.
+        template<class Tr>
+        class CompatTraits; 
+
+        // std::allocator<Ch> in gcc-2.95 is ok, but basic_string only works 
+        // with plain 'std::alloc' still, alt_stringbuf requires a functionnal
+        // alloc template argument, so we need a replacement allocator
+        template<class Alloc>
+        class CompatAlloc; 
+    } // N.S. io
+}// N.S. boost
+
+
+#include <boost/format/detail/config_macros.hpp>
+   // sets-up macros and load compiler-specific workarounds headers.
+
+#if !defined(BOOST_FORMAT_STREAMBUF_DEFINED)
+// workarounds-gcc-2.95 might have defined own streambuf
+#include <streambuf>
+#endif
+
+#if !defined(BOOST_FORMAT_OSTREAM_DEFINED)
+// workarounds-gcc-2.95 might already have included <iostream>
+#include <ostream>
+#endif
+
+
+
+namespace boost {
+    namespace io {
+
+        // **** CompatTraits general definitions : ----------------------------
+        template<class Tr>
+        class CompatTraits
+        {        // general case : be transparent
+        public:
+            typedef Tr  compatible_type;
+        };
+
+        // **** CompatAlloc general definitions : -----------------------------
+        template<class Alloc>
+        class CompatAlloc
+        {        // general case : be transparent
+        public:
+            typedef Alloc  compatible_type;
+        };
+
+    } //N.S. io
+} // N.S. boost
+#endif // include guard
diff --git a/include/boost/format/detail/config_macros.hpp b/include/boost/format/detail/config_macros.hpp
new file mode 100644
index 0000000..44d1e86
--- /dev/null
+++ b/include/boost/format/detail/config_macros.hpp
@@ -0,0 +1,95 @@
+// -*- C++ -*-
+// ----------------------------------------------------------------------------
+// config_macros.hpp : configuration macros for the format library
+// only BOOST_IO_STD is absolutely needed (it should be 'std::' in general)
+// others are compiler-specific workaround macros used in #ifdef switches
+// ----------------------------------------------------------------------------
+
+//  Copyright Samuel Krempp 2003. 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)
+
+// see http://www.boost.org/libs/format for library home page
+
+
+// ----------------------------------------------------------------------------
+
+#ifndef BOOST_FORMAT_CONFIG_MACROS_HPP
+#define BOOST_FORMAT_CONFIG_MACROS_HPP
+
+#include <boost/config.hpp>
+#include <boost/detail/workaround.hpp>
+
+// make sure our local macros wont override something :
+#if defined(BOOST_NO_LOCALE_ISDIGIT) || defined(BOOST_OVERLOAD_FOR_NON_CONST) \
+  || defined(BOOST_IO_STD) || defined( BOOST_IO_NEEDS_USING_DECLARATION ) \
+    || defined(BOOST_NO_TEMPLATE_STD_STREAM) \
+    || defined(BOOST_FORMAT_STREAMBUF_DEFINED) || defined(BOOST_FORMAT_OSTREAM_DEFINED)
+#error "boost::format uses a local macro that is already defined."
+#endif
+
+// specific workarounds. each header can define BOOS_IO_STD if it 
+// needs. (e.g. because of IO_NEEDS_USING_DECLARATION)
+#include <boost/format/detail/workarounds_gcc-2_95.hpp>
+#include <boost/format/detail/workarounds_stlport.hpp>
+
+#ifndef BOOST_IO_STD
+#  define BOOST_IO_STD ::std::
+#endif
+
+#if defined(BOOST_NO_STD_LOCALE) || \
+ ( BOOST_WORKAROUND(__BORLANDC__, <= 0x564) \
+   || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT( 0x570 ) )  )
+// some future __BORLANDC__ >0x564  versions might not need this
+// 0x570 is Borland's kylix branch
+#define BOOST_NO_LOCALE_ISDIGIT
+#endif
+
+#if  BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x570) ) || BOOST_WORKAROUND( BOOST_MSVC, BOOST_TESTED_AT(1300))
+#define BOOST_NO_OVERLOAD_FOR_NON_CONST
+#endif
+
+// **** Workaround for io streams, stlport and msvc.
+#ifdef BOOST_IO_NEEDS_USING_DECLARATION
+namespace boost {
+  using std::char_traits;
+  using std::basic_ostream;
+  namespace io {
+    using std::basic_ostream;
+    namespace detail {
+      using std::basic_ios;
+      using std::basic_ostream;
+    }
+  }
+#if ! defined(BOOST_NO_STD_LOCALE)
+    using std::locale;
+    namespace io {
+        using std::locale;
+        namespace detail {
+            using std::locale;
+        }
+    }
+#endif // locale
+}
+  // -end N.S. boost
+#endif // needs_using_declaration
+
+#if ! defined(BOOST_NO_STD_LOCALE)
+#include <locale>
+#endif
+
+
+// ***  hide std::locale if it doesnt exist. 
+// this typedef is either std::locale or int, avoids placing ifdefs everywhere
+namespace boost { namespace io { namespace detail {
+#if ! defined(BOOST_NO_STD_LOCALE)
+    typedef BOOST_IO_STD locale locale_t;
+#else 
+    typedef int          locale_t;
+#endif
+} } }
+
+
+// ----------------------------------------------------------------------------
+
+#endif // BOOST_FORMAT_MACROS_DEFAULT_HPP
diff --git a/include/boost/format/detail/msvc_disambiguater.hpp b/include/boost/format/detail/msvc_disambiguater.hpp
new file mode 100644
index 0000000..c2692c4
--- /dev/null
+++ b/include/boost/format/detail/msvc_disambiguater.hpp
@@ -0,0 +1,54 @@
+// ----------------------------------------------------------------------------
+// msvc_disambiguater.hpp : msvc workarounds. (for put_{head|last} overloads)
+//               the trick was described in boost's list  by Aleksey Gurtovoy
+// ----------------------------------------------------------------------------
+
+//  Copyright Samuel Krempp 2003. 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)
+
+// see http://www.boost.org/libs/format for library home page
+
+// ----------------------------------------------------------------------------
+
+#ifndef BOOST_MSVC_DISAMBIGUATER_HPP
+#define BOOST_MSVC_DISAMBIGUATER_HPP
+
+#if BOOST_WORKAROUND(__DECCXX_VER, BOOST_TESTED_AT(60590042))
+
+#include <boost/format/group.hpp>
+#include <ostream>
+
+namespace boost {
+namespace io {
+namespace detail {
+
+template< class Ch, class Tr, class T >
+struct disambiguater
+{
+   template< typename U >
+   static void put_head(BOOST_IO_STD basic_ostream<Ch, Tr>& os, group1<U> const& x, long)
+   {
+       os << group_head(x.a1_); 
+   }
+   static void put_head(BOOST_IO_STD basic_ostream<Ch, Tr>& os, T const& x, int)
+   {
+   }
+   template< typename U >
+   static void put_last(BOOST_IO_STD basic_ostream<Ch, Tr>& os, group1<U> const& x, long)
+   {
+       os << group_last(x.a1_); 
+   }
+   static void put_last(BOOST_IO_STD basic_ostream<Ch, Tr>& os, T const& x, int)
+   {
+     os << x;
+   }
+};
+
+} // namespace detail
+} // namespace io
+} // namespace boost
+
+#endif // -__DECCXX_VER
+
+#endif // -BOOST_MSVC_DISAMBIGUATER_HPP
diff --git a/include/boost/format/detail/unset_macros.hpp b/include/boost/format/detail/unset_macros.hpp
new file mode 100644
index 0000000..b3ac47b
--- /dev/null
+++ b/include/boost/format/detail/unset_macros.hpp
@@ -0,0 +1,34 @@
+// ----------------------------------------------------------------------------
+// unset_macros.hpp
+// ----------------------------------------------------------------------------
+
+//  Copyright Samuel Krempp 2003. 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)
+
+//  See http://www.boost.org/libs/format for library home page
+
+// ----------------------------------------------------------------------------
+
+// *** Undefine 'local' macros :
+#ifdef BOOST_NO_OVERLOAD_FOR_NON_CONST
+#undef BOOST_NO_OVERLOAD_FOR_NON_CONST
+#endif
+#ifdef BOOST_NO_LOCALE_ISDIGIT
+#undef BOOST_NO_LOCALE_ISDIGIT
+#endif
+#ifdef BOOST_IO_STD
+#undef BOOST_IO_STD
+#endif
+#ifdef BOOST_IO_NEEDS_USING_DECLARATION
+#undef BOOST_IO_NEEDS_USING_DECLARATION
+#endif
+#ifdef BOOST_NO_TEMPLATE_STD_STREAM
+#undef BOOST_NO_TEMPLATE_STD_STREAM
+#endif
+#ifdef BOOST_FORMAT_STREAMBUF_DEFINED
+#undef BOOST_FORMAT_STREAMBUF_DEFINED
+#endif
+#ifdef BOOST_FORMAT_OSTREAM_DEFINED
+#undef BOOST_FORMAT_OSTREAM_DEFINED
+#endif
diff --git a/include/boost/format/detail/workarounds_gcc-2_95.hpp b/include/boost/format/detail/workarounds_gcc-2_95.hpp
new file mode 100644
index 0000000..8c49d42
--- /dev/null
+++ b/include/boost/format/detail/workarounds_gcc-2_95.hpp
@@ -0,0 +1,162 @@
+// ----------------------------------------------------------------------------
+//  workarounds for gcc < 3.0. 
+// ----------------------------------------------------------------------------
+
+//  Copyright Samuel Krempp 2003. 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)
+
+//  See http://www.boost.org/libs/format for library home page
+
+
+// ----------------------------------------------------------------------------
+
+// There's a lot to do, the stdlib shipped with gcc prior to 3.x 
+// was terribly non-conforming. 
+// . defines macros switches
+// . supplies template classes basic_foo<char,Tr> where gcc only supplies foo.
+//  i.e :
+//     -  basic_ios<char, Tr>        from ios
+//     -  basic_ostream<char, Tr>    from ostream
+//     -  basic_srteambuf<char, Tr>  from streambuf
+// these can be used transparently. (it obviously does not work for wchar_t)
+// . specialise CompatAlloc and CompatTraits to wrap gcc-2.95's 
+//    string_char_traits and std::alloc 
+
+#if  BOOST_WORKAROUND(__GNUC__, < 3) && !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION)
+   // only for gcc-2.95's native stdlib
+
+#ifndef BOOST_FORMAT_WORKAROUNDS_GCC295_H
+#define BOOST_FORMAT_WORKAROUNDS_GCC295_H
+
+// SGI STL doesnt have <ostream> and others, so we need iostream.
+#include <iostream> 
+#define BOOST_FORMAT_OSTREAM_DEFINED
+
+#include <streambuf.h>
+#define BOOST_FORMAT_STREAMBUF_DEFINED
+
+#define BOOST_NO_TEMPLATE_STD_STREAM
+
+#ifndef BOOST_IO_STD
+#  define BOOST_IO_STD std::
+#endif
+
+
+
+// *** 
+// gcc's simple classes turned into standard-like template classes :
+
+namespace std {
+
+
+    // gcc has string_char_traits, it's incomplete.
+    // we declare a std::char_traits, and specialize CompatTraits<..> on it
+    // to do what is required
+    template<class Ch>
+    class char_traits; // no definition here, we will just use it as a tag.
+
+    template <class Ch, class Tr>
+    class basic_streambuf;
+
+    template <class Tr> 
+    class basic_streambuf<char, Tr> : public streambuf {
+    };
+
+    template <class Ch, class Tr=::std::char_traits<Ch> >
+    class basic_ios;
+
+    template <class Tr>
+    class basic_ios<char, Tr> : public ostream {
+    public:
+        basic_ios(streambuf * p) : ostream(p) {};
+         char fill()  const { return ios::fill(); } // gcc returns wchar..
+         char fill(char c)  { return ios::fill(c); } // gcc takes wchar..
+         char widen(char c) { return c; }
+         char narrow(char c, char def) { return c; }
+        basic_ios& copyfmt(const ios& right) {
+            fill(right.fill());
+            flags(right.flags() );
+            exceptions(right.exceptions());
+            width(right.width());
+            precision(right.precision());
+            return *this;
+        }
+     };
+
+
+    typedef ios ios_base;
+
+    template <class Ch, class Tr>
+    class basic_ostream;
+
+     template <class Tr> 
+     class basic_ostream<char, Tr> : public basic_ios<char, Tr>
+     {
+     public:
+         basic_ostream(streambuf * p) : basic_ios<char,Tr> (p) {}
+     };
+
+} // namespace std
+
+
+namespace boost {
+    namespace io {
+
+
+        // ** CompatTraits gcc2.95 specialisations ----------------------------
+        template<class Ch>
+        class CompatTraits< ::std::string_char_traits<Ch> >
+            : public ::std::string_char_traits<Ch> 
+        {
+        public:
+            typedef CompatTraits                compatible_type;
+
+            typedef Ch char_type;
+            typedef int int_type;
+            typedef ::std::streampos pos_type;
+            typedef ::std::streamoff off_type;
+        
+            static char_type 
+            to_char_type(const int_type& meta) {
+                return static_cast<char_type>(meta); }
+            static int_type 
+            to_int_type(const char_type& ch) {
+                return static_cast<int_type>(static_cast<unsigned char>(ch) );}
+            static bool 
+            eq_int_type(const int_type& left, const int_type& right) {
+                return left == right; }
+            static int_type 
+            eof() {
+                return static_cast<int_type>(EOF);
+            }
+            static int_type 
+            not_eof(const int_type& meta) {
+                return (meta == eof()) ? 0 : meta;
+            }
+        };
+
+        template<class Ch>
+        class CompatTraits< ::std::char_traits<Ch> > {
+        public:
+            typedef CompatTraits< ::std::string_char_traits<Ch> >  compatible_type;
+        };
+
+        // ** CompatAlloc gcc-2.95  specialisations ---------------------------
+        template<>
+        class CompatAlloc< ::std::alloc>
+        {
+        public:
+            typedef ::std::allocator<char> compatible_type;
+        };
+
+    } // N.S. io
+} // N.S. boost
+
+
+
+
+
+#endif // include guard
+
+#endif // if workaround
diff --git a/include/boost/format/detail/workarounds_stlport.hpp b/include/boost/format/detail/workarounds_stlport.hpp
new file mode 100644
index 0000000..5d435b9
--- /dev/null
+++ b/include/boost/format/detail/workarounds_stlport.hpp
@@ -0,0 +1,36 @@
+// ----------------------------------------------------------------------------
+// workarounds_stlport.hpp : workaround STLport issues
+// ----------------------------------------------------------------------------
+
+//  Copyright Samuel Krempp 2003. 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)
+
+// see http://www.boost.org/libs/format for library home page
+
+// ----------------------------------------------------------------------------
+
+#ifndef BOOST_MACROS_STLPORT_HPP
+#define BOOST_MACROS_STLPORT_HPP
+
+// *** This should go to "boost/config/stdlib/stlport.hpp".
+
+// If the streams are not native and there are problems with using templates
+// accross namespaces, we define some macros to enable a workaround for this.
+
+// STLport 4.5
+#if !defined(_STLP_OWN_IOSTREAMS) && defined(_STLP_USE_NAMESPACES) && defined(BOOST_NO_USING_TEMPLATE)
+#  define BOOST_IO_STD 
+#  define BOOST_IO_NEEDS_USING_DECLARATION
+#endif
+
+// STLport 4.0
+#if !defined(__SGI_STL_OWN_IOSTREAMS) && defined(__STL_USE_OWN_NAMESPACE) && defined(BOOST_NO_USING_TEMPLATE)
+#  define BOOST_IO_STD 
+#  define BOOST_IO_NEEDS_USING_DECLARATION
+#endif
+
+
+// ----------------------------------------------------------------------------
+
+#endif // BOOST_MACROS_STLPORT_HPP
diff --git a/include/boost/format/exceptions.hpp b/include/boost/format/exceptions.hpp
new file mode 100644
index 0000000..56ee30d
--- /dev/null
+++ b/include/boost/format/exceptions.hpp
@@ -0,0 +1,103 @@
+// ----------------------------------------------------------------------------
+// boost/format/exceptions.hpp 
+// ----------------------------------------------------------------------------
+
+//  Copyright Samuel Krempp 2003.
+//
+// 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)
+//
+//
+//  See http://www.boost.org/libs/format/ for library home page
+
+// ----------------------------------------------------------------------------
+
+#ifndef BOOST_FORMAT_EXCEPTIONS_HPP
+#define BOOST_FORMAT_EXCEPTIONS_HPP
+
+
+#include <stdexcept>
+
+
+namespace boost {
+
+    namespace io {
+
+// **** exceptions -----------------------------------------------
+
+        class format_error : public std::exception
+        {
+        public:
+            format_error()  {}
+            virtual const char *what() const throw() {
+                return "boost::format_error: "
+                    "format generic failure";
+            }
+        };
+
+        class bad_format_string : public format_error
+        {
+            std::size_t pos_, next_;
+        public:
+            bad_format_string(std::size_t pos, std::size_t size) 
+                : pos_(pos), next_(size) {}
+            std::size_t get_pos() const { return pos_; }
+            std::size_t get_next() const { return next_; }
+            virtual const char *what() const throw() {
+                return "boost::bad_format_string: format-string is ill-formed";
+            }
+        };
+
+        class too_few_args : public format_error
+        {
+            std::size_t cur_, expected_;
+        public:
+            too_few_args(std::size_t cur, std::size_t expected) 
+                : cur_(cur), expected_(expected) {}
+            std::size_t get_cur() const { return cur_; }
+            std::size_t get_expected() const { return expected_; }
+            virtual const char *what() const throw() {
+                return "boost::too_few_args: "
+                    "format-string referred to more arguments than were passed";
+            }
+        };
+
+        class too_many_args : public format_error
+        {
+            std::size_t cur_, expected_;
+        public:
+            too_many_args(std::size_t cur, std::size_t expected) 
+                : cur_(cur), expected_(expected) {}
+            std::size_t get_cur() const { return cur_; }
+            std::size_t get_expected() const { return expected_; }
+            virtual const char *what() const throw() {
+                return "boost::too_many_args: "
+                    "format-string referred to fewer arguments than were passed";
+            }
+        };
+
+
+        class  out_of_range : public format_error
+        {
+            int index_, beg_, end_;    // range is [ beg, end [
+        public:
+            out_of_range(int index, int beg, int end) 
+                : index_(index), beg_(beg), end_(end) {}
+            int get_index() const { return index_; }
+            int get_beg() const { return beg_; }
+            int get_end() const { return end_; }
+            virtual const char *what() const throw() {
+                return "boost::out_of_range: "
+                    "tried to refer to an argument (or item) number which"
+                    " is out of range, according to the format string";
+            }
+        };
+
+
+    } // namespace io
+
+} // namespace boost
+
+
+#endif // BOOST_FORMAT_EXCEPTIONS_HPP
diff --git a/include/boost/format/feed_args.hpp b/include/boost/format/feed_args.hpp
new file mode 100644
index 0000000..b0e520e
--- /dev/null
+++ b/include/boost/format/feed_args.hpp
@@ -0,0 +1,321 @@
+// ----------------------------------------------------------------------------
+//  feed_args.hpp :  functions for processing each argument 
+//                      (feed, feed_manip, and distribute)
+// ----------------------------------------------------------------------------
+
+//  Copyright Samuel Krempp 2003. 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)
+
+//  See http://www.boost.org/libs/format for library home page
+
+// ----------------------------------------------------------------------------
+
+#ifndef BOOST_FORMAT_FEED_ARGS_HPP
+#define BOOST_FORMAT_FEED_ARGS_HPP
+
+#include <boost/config.hpp>
+#include <boost/assert.hpp>
+#include <boost/throw_exception.hpp>
+
+#include <boost/format/format_class.hpp>
+#include <boost/format/group.hpp>
+#include <boost/format/detail/msvc_disambiguater.hpp>
+
+namespace boost {
+namespace io {
+namespace detail {
+
+    template<class Ch, class Tr, class Alloc>
+    void mk_str( std::basic_string<Ch,Tr, Alloc> & res, 
+                 const Ch * beg,
+                 typename std::basic_string<Ch,Tr,Alloc>::size_type size,
+                 std::streamsize w, 
+                 const Ch fill_char,
+                 std::ios_base::fmtflags f, 
+                 const Ch prefix_space, // 0 if no space-padding
+                 bool center) 
+    // applies centered/left/right  padding  to the string  [beg, beg+size[
+    // Effects : the result is placed in res.
+    {
+        typedef typename std::basic_string<Ch,Tr,Alloc>::size_type size_type;
+        res.resize(0);
+        if(w<=0 || static_cast<size_type>(w) <=size) {
+            // no need to pad.
+            res.reserve(size + !!prefix_space);
+            if(prefix_space) 
+              res.append(1, prefix_space);
+            if (size)
+              res.append(beg, size);
+        }
+        else { 
+            std::streamsize n=static_cast<std::streamsize>(w-size-!!prefix_space);
+            std::streamsize n_after = 0, n_before = 0; 
+            res.reserve(static_cast<size_type>(w)); // allocate once for the 2 inserts
+            if(center) 
+                n_after = n/2, n_before = n - n_after; 
+            else 
+                if(f & std::ios_base::left)
+                    n_after = n;
+                else
+                    n_before = n;
+            // now make the res string :
+            if(n_before) res.append(static_cast<size_type>(n_before), fill_char);
+            if(prefix_space) 
+              res.append(1, prefix_space);
+            if (size)  
+              res.append(beg, size);
+            if(n_after) res.append(static_cast<size_type>(n_after), fill_char);
+        }
+    } // -mk_str(..) 
+
+
+#if BOOST_WORKAROUND(__DECCXX_VER, BOOST_TESTED_AT(60590042))
+// __DECCXX needs to be tricked to disambiguate this simple overload..
+// the trick is in "boost/format/msvc_disambiguater.hpp"
+  
+    template< class Ch, class Tr, class T> inline
+    void put_head (BOOST_IO_STD basic_ostream<Ch, Tr> & os, const T& x ) {
+        disambiguater<Ch, Tr, T>::put_head(os, x, 1L);
+    }
+    template< class Ch, class Tr, class T> inline
+    void put_last (BOOST_IO_STD basic_ostream<Ch, Tr> & os, const T& x ) {
+        disambiguater<Ch, Tr, T>::put_last(os, x, 1L);
+    }
+
+#else  
+
+    template< class Ch, class Tr, class T> inline
+    void put_head (BOOST_IO_STD basic_ostream<Ch, Tr> &, const T& ) {
+    }
+
+    template< class Ch, class Tr, class T> inline
+    void put_head( BOOST_IO_STD basic_ostream<Ch, Tr> & os, const group1<T>& x ) {
+        os << group_head(x.a1_); // send the first N-1 items, not the last
+    }
+
+    template< class Ch, class Tr, class T> inline
+    void put_last( BOOST_IO_STD basic_ostream<Ch, Tr> & os, const T& x ) {
+        os << x ;
+    }
+
+    template< class Ch, class Tr, class T> inline
+    void put_last( BOOST_IO_STD basic_ostream<Ch, Tr> & os, const group1<T>& x ) {
+        os << group_last(x.a1_); // this selects the last element
+    }
+
+#ifndef BOOST_NO_OVERLOAD_FOR_NON_CONST 
+    template< class Ch, class Tr, class T> inline
+    void put_head( BOOST_IO_STD basic_ostream<Ch, Tr> &, T& ) {
+    }
+
+    template< class Ch, class Tr, class T> inline
+    void put_last( BOOST_IO_STD basic_ostream<Ch, Tr> & os, T& x) {
+        os << x ;
+    }
+#endif
+#endif  // -__DECCXX workaround
+
+    template< class Ch, class Tr, class T>
+    void call_put_head(BOOST_IO_STD basic_ostream<Ch, Tr> & os, const void* x) {
+        put_head(os, *(static_cast<T const *>(x)));
+    }
+
+    template< class Ch, class Tr, class T>
+    void call_put_last(BOOST_IO_STD basic_ostream<Ch, Tr> & os, const void* x) {
+        put_last(os, *(static_cast<T const *>(x)));
+    }
+
+    template< class Ch, class Tr>
+    struct put_holder {
+        template<class T>
+        put_holder(T& t)
+          : arg(&t),
+            put_head(&call_put_head<Ch, Tr, T>),
+            put_last(&call_put_last<Ch, Tr, T>)
+        {}
+        const void* arg;
+        void (*put_head)(BOOST_IO_STD basic_ostream<Ch, Tr> & os, const void* x);
+        void (*put_last)(BOOST_IO_STD basic_ostream<Ch, Tr> & os, const void* x);
+    };
+    
+    template< class Ch, class Tr> inline
+    void put_head( BOOST_IO_STD basic_ostream<Ch, Tr> & os, const put_holder<Ch, Tr>& t) {
+        t.put_head(os, t.arg);
+    }
+    
+    template< class Ch, class Tr> inline
+    void put_last( BOOST_IO_STD basic_ostream<Ch, Tr> & os, const put_holder<Ch, Tr>& t) {
+        t.put_last(os, t.arg);
+    }
+
+
+    template< class Ch, class Tr, class Alloc, class T> 
+    void put( T x, 
+              const format_item<Ch, Tr, Alloc>& specs, 
+              typename basic_format<Ch, Tr, Alloc>::string_type& res, 
+              typename basic_format<Ch, Tr, Alloc>::internal_streambuf_t & buf,
+              io::detail::locale_t *loc_p = NULL)
+    {
+#ifdef BOOST_MSVC
+       // If std::min<unsigned> or std::max<unsigned> are already instantiated
+       // at this point then we get a blizzard of warning messages when we call
+       // those templates with std::size_t as arguments.  Weird and very annoyning...
+#pragma warning(push)
+#pragma warning(disable:4267)
+#endif
+        // does the actual conversion of x, with given params, into a string
+        // using the supplied stringbuf.
+
+        typedef typename basic_format<Ch, Tr, Alloc>::string_type   string_type;
+        typedef typename basic_format<Ch, Tr, Alloc>::format_item_t format_item_t;
+        typedef typename string_type::size_type size_type;
+
+        basic_oaltstringstream<Ch, Tr, Alloc>  oss( &buf);
+
+#if !defined(BOOST_NO_STD_LOCALE)
+        if(loc_p != NULL)
+            oss.imbue(*loc_p);
+#endif
+
+        specs.fmtstate_.apply_on(oss, loc_p);
+
+        // the stream format state can be modified by manipulators in the argument :
+        put_head( oss, x );
+        // in case x is a group, apply the manip part of it, 
+        // in order to find width
+
+        const std::ios_base::fmtflags fl=oss.flags();
+        const bool internal = (fl & std::ios_base::internal) != 0;
+        const std::streamsize w = oss.width();
+        const bool two_stepped_padding= internal && (w!=0);
+      
+        res.resize(0);
+        if(! two_stepped_padding) {
+            if(w>0) // handle padding via mk_str, not natively in stream 
+                oss.width(0);
+            put_last( oss, x);
+            const Ch * res_beg = buf.pbase();
+            Ch prefix_space = 0;
+            if(specs.pad_scheme_ & format_item_t::spacepad)
+                if(buf.pcount()== 0 || 
+                   (res_beg[0] !=oss.widen('+') && res_beg[0] !=oss.widen('-')  ))
+                    prefix_space = oss.widen(' ');
+            size_type res_size = (std::min)(
+                (static_cast<size_type>((specs.truncate_ & (std::numeric_limits<size_type>::max)())) - !!prefix_space), 
+                buf.pcount() );
+            mk_str(res, res_beg, res_size, w, oss.fill(), fl, 
+                   prefix_space, (specs.pad_scheme_ & format_item_t::centered) !=0 );
+        }
+        else  { // 2-stepped padding
+            // internal can be implied by zeropad, or user-set.
+            // left, right, and centered alignment overrule internal,
+            // but spacepad or truncate might be mixed with internal (using manipulator)
+            put_last( oss, x); // may pad
+            const Ch * res_beg = buf.pbase();
+            size_type res_size = buf.pcount();
+            bool prefix_space=false;
+            if(specs.pad_scheme_ & format_item_t::spacepad)
+                if(buf.pcount()== 0 || 
+                   (res_beg[0] !=oss.widen('+') && res_beg[0] !=oss.widen('-')  ))
+                    prefix_space = true;
+            if(res_size == static_cast<size_type>(w) && w<=specs.truncate_ && !prefix_space) {
+                // okay, only one thing was printed and padded, so res is fine
+                res.assign(res_beg, res_size);
+            }
+            else { //   length w exceeded
+                // either it was multi-output with first output padding up all width..
+                // either it was one big arg and we are fine.
+                // Note that res_size<w is possible  (in case of bad user-defined formatting)
+                res.assign(res_beg, res_size);
+                res_beg=NULL;  // invalidate pointers.
+                
+                // make a new stream, to start re-formatting from scratch :
+                buf.clear_buffer();
+                basic_oaltstringstream<Ch, Tr, Alloc>  oss2( &buf);
+                specs.fmtstate_.apply_on(oss2, loc_p);
+                put_head( oss2, x );
+
+                oss2.width(0);
+                if(prefix_space)
+                    oss2 << ' ';
+                put_last(oss2, x );
+                if(buf.pcount()==0 && specs.pad_scheme_ & format_item_t::spacepad) {
+                    prefix_space =true;
+                    oss2 << ' ';
+                }
+                // we now have the minimal-length output
+                const Ch * tmp_beg = buf.pbase();
+                size_type tmp_size = (std::min)(
+                    (static_cast<size_type>(specs.truncate_ & (std::numeric_limits<size_type>::max)())),
+                    buf.pcount());
+                
+                if(static_cast<size_type>(w) <= tmp_size) { 
+                    // minimal length is already >= w, so no padding (cool!)
+                        res.assign(tmp_beg, tmp_size);
+                }
+                else { // hum..  we need to pad (multi_output, or spacepad present)
+                    //find where we should pad
+                    size_type sz = (std::min)(res_size + (prefix_space ? 1 : 0), tmp_size);
+                    size_type i = prefix_space;
+                    for(; i<sz && tmp_beg[i] == res[i - (prefix_space ? 1 : 0)]; ++i) {}
+                    if(i>=tmp_size) i=prefix_space;
+                    res.assign(tmp_beg, i);
+                                        std::streamsize d = w - static_cast<std::streamsize>(tmp_size);
+                                        BOOST_ASSERT(d>0);
+                    res.append(static_cast<size_type>( d ), oss2.fill());
+                    res.append(tmp_beg+i, tmp_size-i);
+                    BOOST_ASSERT(i+(tmp_size-i)+(std::max)(d,(std::streamsize)0) 
+                                 == static_cast<size_type>(w));
+                    BOOST_ASSERT(res.size() == static_cast<size_type>(w));
+                }
+            }
+        }
+        buf.clear_buffer();
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+    } // end- put(..)
+
+
+    template< class Ch, class Tr, class Alloc, class T> 
+    void distribute (basic_format<Ch,Tr, Alloc>& self, T x) {
+        // call put(x, ..) on every occurrence of the current argument :
+        if(self.cur_arg_ >= self.num_args_)  {
+            if( self.exceptions() & too_many_args_bit )
+                boost::throw_exception(too_many_args(self.cur_arg_, self.num_args_)); 
+            else return;
+        }
+        for(unsigned long i=0; i < self.items_.size(); ++i) {
+            if(self.items_[i].argN_ == self.cur_arg_) {
+                put<Ch, Tr, Alloc, T> (x, self.items_[i], self.items_[i].res_, 
+                                self.buf_, boost::get_pointer(self.loc_) );
+            }
+        }
+    }
+
+    template<class Ch, class Tr, class Alloc, class T> 
+    basic_format<Ch, Tr, Alloc>&  
+    feed_impl (basic_format<Ch,Tr, Alloc>& self, T x) {
+        if(self.dumped_) self.clear();
+        distribute<Ch, Tr, Alloc, T> (self, x);
+        ++self.cur_arg_;
+        if(self.bound_.size() != 0) {
+                while( self.cur_arg_ < self.num_args_ && self.bound_[self.cur_arg_] )
+                    ++self.cur_arg_;
+        }
+        return self;
+    }
+
+    template<class Ch, class Tr, class Alloc, class T> inline
+    basic_format<Ch, Tr, Alloc>&  
+    feed (basic_format<Ch,Tr, Alloc>& self, T x) {
+        return feed_impl<Ch, Tr, Alloc, const put_holder<Ch, Tr>&>(self, put_holder<Ch, Tr>(x));
+    }
+    
+} // namespace detail
+} // namespace io
+} // namespace boost
+
+
+#endif //  BOOST_FORMAT_FEED_ARGS_HPP
diff --git a/include/boost/format/format_class.hpp b/include/boost/format/format_class.hpp
new file mode 100644
index 0000000..ae98be4
--- /dev/null
+++ b/include/boost/format/format_class.hpp
@@ -0,0 +1,180 @@
+// ----------------------------------------------------------------------------
+//  format_class.hpp :  class interface
+// ----------------------------------------------------------------------------
+
+//  Copyright Samuel Krempp 2003. 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)
+
+//  See http://www.boost.org/libs/format for library home page
+
+// ----------------------------------------------------------------------------
+
+#ifndef BOOST_FORMAT_CLASS_HPP
+#define BOOST_FORMAT_CLASS_HPP
+
+
+#include <vector>
+#include <string>
+
+#include <boost/optional.hpp> // to store locale when needed
+
+#include <boost/format/format_fwd.hpp>
+#include <boost/format/internals_fwd.hpp>
+#include <boost/format/internals.hpp>
+#include <boost/format/alt_sstream.hpp>
+
+namespace boost {
+
+    template<class Ch, class Tr, class Alloc>
+    class basic_format 
+    {
+        typedef typename io::CompatTraits<Tr>::compatible_type compat_traits;  
+    public:
+        typedef Ch  CharT;   // borland fails in operator% if we use Ch and Tr directly
+        typedef std::basic_string<Ch, Tr, Alloc>              string_type;
+        typedef typename string_type::size_type               size_type;
+        typedef io::detail::format_item<Ch, Tr, Alloc>        format_item_t;
+        typedef io::basic_altstringbuf<Ch, Tr, Alloc>         internal_streambuf_t;
+        
+
+        explicit basic_format(const Ch* str=NULL);
+        explicit basic_format(const string_type& s);
+        basic_format(const basic_format& x);
+        basic_format& operator= (const basic_format& x);
+        void swap(basic_format& x);
+
+#if !defined(BOOST_NO_STD_LOCALE)
+        explicit basic_format(const Ch* str, const std::locale & loc);
+        explicit basic_format(const string_type& s, const std::locale & loc);
+#endif
+        io::detail::locale_t  getloc() const;
+
+        basic_format& clear();       // empty all converted string buffers (except bound items)
+        basic_format& clear_binds(); // unbind all bound items, and call clear()
+        basic_format& parse(const string_type&); // resets buffers and parse a new format string
+
+        // ** formatted result ** //
+        size_type   size() const;    // sum of the current string pieces sizes
+        string_type str()  const;    // final string 
+
+        // ** arguments passing ** //
+        template<class T>  
+        basic_format&   operator%(const T& x)
+            { return io::detail::feed<CharT, Tr, Alloc, const T&>(*this,x); }
+
+#ifndef BOOST_NO_OVERLOAD_FOR_NON_CONST
+        template<class T>  basic_format&   operator%(T& x) 
+            { return io::detail::feed<CharT, Tr, Alloc, T&>(*this,x); }
+#endif
+
+        template<class T>
+        basic_format& operator%(volatile const T& x)
+            { /* make a non-volatile copy */ const T v(x);
+              /* pass the copy along      */ return io::detail::feed<CharT, Tr, Alloc, const T&>(*this, v); }
+
+#ifndef BOOST_NO_OVERLOAD_FOR_NON_CONST
+        template<class T>
+        basic_format& operator%(volatile T& x)
+            { /* make a non-volatile copy */ T v(x);
+              /* pass the copy along      */ return io::detail::feed<CharT, Tr, Alloc, T&>(*this, v); }
+#endif
+
+#if defined(__GNUC__)
+        // GCC can't handle anonymous enums without some help
+        // ** arguments passing ** //
+        basic_format&   operator%(const int& x)
+            { return io::detail::feed<CharT, Tr, Alloc, const int&>(*this,x); }
+
+#ifndef BOOST_NO_OVERLOAD_FOR_NON_CONST
+        basic_format&   operator%(int& x)
+            { return io::detail::feed<CharT, Tr, Alloc, int&>(*this,x); }
+#endif
+#endif
+
+        // The total number of arguments expected to be passed to the format objectt
+        int expected_args() const
+            { return num_args_; }
+        // The number of arguments currently bound (see bind_arg(..) )
+        int bound_args() const;
+        // The number of arguments currently fed to the format object
+        int fed_args() const;
+        // The index (1-based) of the current argument (i.e. next to be formatted)
+        int cur_arg() const;
+        // The number of arguments still required to be fed
+        int remaining_args() const; // same as expected_args() - bound_args() - fed_args()
+
+
+        // ** object modifying **//
+        template<class T>
+        basic_format&  bind_arg(int argN, const T& val) 
+            { return io::detail::bind_arg_body(*this, argN, val); }
+        basic_format&  clear_bind(int argN);
+        template<class T> 
+        basic_format&  modify_item(int itemN, T manipulator) 
+            { return io::detail::modify_item_body<Ch,Tr, Alloc, T> (*this, itemN, manipulator);}
+
+        // Choosing which errors will throw exceptions :
+        unsigned char exceptions() const;
+        unsigned char exceptions(unsigned char newexcept);
+
+#if !defined( BOOST_NO_MEMBER_TEMPLATE_FRIENDS )  \
+    && !BOOST_WORKAROUND(__BORLANDC__, <= 0x570) \
+    && !BOOST_WORKAROUND( _CRAYC, != 0) \
+    && !BOOST_WORKAROUND(__DECCXX_VER, BOOST_TESTED_AT(60590042))
+        // use friend templates and private members only if supported
+
+#ifndef  BOOST_NO_TEMPLATE_STD_STREAM
+        template<class Ch2, class Tr2, class Alloc2>
+        friend std::basic_ostream<Ch2, Tr2> & 
+        operator<<( std::basic_ostream<Ch2, Tr2> & ,
+                    const basic_format<Ch2, Tr2, Alloc2>& );
+#else
+        template<class Ch2, class Tr2, class Alloc2>
+        friend std::ostream & 
+        operator<<( std::ostream & ,
+                    const basic_format<Ch2, Tr2, Alloc2>& );
+#endif
+
+        template<class Ch2, class Tr2, class Alloc2, class T>  
+        friend basic_format<Ch2, Tr2, Alloc2>&  
+        io::detail::feed_impl (basic_format<Ch2, Tr2, Alloc2>&, T);
+
+        template<class Ch2, class Tr2, class Alloc2, class T>  friend   
+        void io::detail::distribute (basic_format<Ch2, Tr2, Alloc2>&, T);
+        
+        template<class Ch2, class Tr2, class Alloc2, class T>  friend
+        basic_format<Ch2, Tr2, Alloc2>& 
+        io::detail::modify_item_body (basic_format<Ch2, Tr2, Alloc2>&, int, T);
+        
+        template<class Ch2, class Tr2, class Alloc2, class T> friend
+        basic_format<Ch2, Tr2, Alloc2>&  
+        io::detail::bind_arg_body (basic_format<Ch2, Tr2, Alloc2>&, int, const T&);
+
+    private:
+#endif
+        typedef io::detail::stream_format_state<Ch, Tr>  stream_format_state;
+        // flag bits, used for style_
+        enum style_values  { ordered = 1, // set only if all directives are  positional
+                             special_needs = 4 };     
+
+        void make_or_reuse_data(std::size_t nbitems);// used for (re-)initialisation
+
+        // member data --------------------------------------------//
+        std::vector<format_item_t>  items_; // each '%..' directive leads to a format_item
+        std::vector<bool> bound_; // stores which arguments were bound. size() == 0 || num_args
+
+        int              style_; // style of format-string :  positional or not, etc
+        int             cur_arg_; // keep track of wich argument is current
+        int            num_args_; // number of expected arguments
+        mutable bool     dumped_; // true only after call to str() or <<
+        string_type      prefix_; // piece of string to insert before first item
+        unsigned char exceptions_;
+        internal_streambuf_t   buf_; // the internal stream buffer.
+        boost::optional<io::detail::locale_t>     loc_;
+    }; // class basic_format
+
+} // namespace boost
+
+
+#endif // BOOST_FORMAT_CLASS_HPP
diff --git a/include/boost/format/format_fwd.hpp b/include/boost/format/format_fwd.hpp
new file mode 100644
index 0000000..16b8565
--- /dev/null
+++ b/include/boost/format/format_fwd.hpp
@@ -0,0 +1,43 @@
+// ----------------------------------------------------------------------------
+//  format_fwd.hpp :  forward declarations
+// ----------------------------------------------------------------------------
+
+//  Copyright Samuel Krempp 2003. 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)
+
+//  See http://www.boost.org/libs/format for library home page
+
+// ----------------------------------------------------------------------------
+
+#ifndef BOOST_FORMAT_FWD_HPP
+#define BOOST_FORMAT_FWD_HPP
+
+#include <string>
+#include <iosfwd>
+
+#include <boost/format/detail/compat_workarounds.hpp> 
+
+namespace boost {
+
+    template <class Ch, 
+        class Tr = BOOST_IO_STD char_traits<Ch>, class Alloc = std::allocator<Ch> >
+    class basic_format;
+
+    typedef basic_format<char >     format;
+
+#if !defined(BOOST_NO_STD_WSTRING)  && !defined(BOOST_NO_STD_WSTREAMBUF)
+    typedef basic_format<wchar_t >  wformat;
+#endif
+
+    namespace io {
+        enum format_error_bits { bad_format_string_bit = 1, 
+                                 too_few_args_bit = 2, too_many_args_bit = 4,
+                                 out_of_range_bit = 8,
+                                 all_error_bits = 255, no_error_bits=0 };
+                  
+    } // namespace io
+
+} // namespace boost
+
+#endif // BOOST_FORMAT_FWD_HPP
diff --git a/include/boost/format/format_implementation.hpp b/include/boost/format/format_implementation.hpp
new file mode 100644
index 0000000..2abb5c4
--- /dev/null
+++ b/include/boost/format/format_implementation.hpp
@@ -0,0 +1,329 @@
+// ----------------------------------------------------------------------------
+// format_implementation.hpp  Implementation of the basic_format class
+// ----------------------------------------------------------------------------
+
+//  Copyright Samuel Krempp 2003. 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)
+
+//  See http://www.boost.org/libs/format for library home page
+
+
+// ----------------------------------------------------------------------------
+
+#ifndef BOOST_FORMAT_IMPLEMENTATION_HPP
+#define BOOST_FORMAT_IMPLEMENTATION_HPP
+
+#include <boost/config.hpp>
+#include <boost/throw_exception.hpp>
+#include <boost/assert.hpp>
+#include <boost/format/format_class.hpp>
+#include <algorithm> // std::swap
+
+namespace boost {
+
+// ---  basic_format implementation -----------------------------------------//
+
+    template< class Ch, class Tr, class Alloc>
+    basic_format<Ch, Tr, Alloc>:: basic_format(const Ch* s)
+        : style_(0), cur_arg_(0), num_args_(0), dumped_(false),
+          exceptions_(io::all_error_bits)
+    {
+        if( s)
+            parse( s );
+    }
+
+#if !defined(BOOST_NO_STD_LOCALE)
+    template< class Ch, class Tr, class Alloc>
+    basic_format<Ch, Tr, Alloc>:: basic_format(const Ch* s, const std::locale & loc)
+        : style_(0), cur_arg_(0), num_args_(0), dumped_(false),
+          exceptions_(io::all_error_bits), loc_(loc)
+    {
+        if(s) parse( s );
+    }
+
+    template< class Ch, class Tr, class Alloc>
+    basic_format<Ch, Tr, Alloc>:: basic_format(const string_type& s, const std::locale & loc)
+        : style_(0), cur_arg_(0), num_args_(0), dumped_(false),
+          exceptions_(io::all_error_bits), loc_(loc)
+    {
+        parse(s);  
+    }
+#endif // ! BOOST_NO_STD_LOCALE
+    template< class Ch, class Tr, class Alloc>
+    io::detail::locale_t basic_format<Ch, Tr, Alloc>:: 
+    getloc() const {
+        return loc_ ? loc_.get() : io::detail::locale_t(); 
+    }
+
+    template< class Ch, class Tr, class Alloc>
+    basic_format<Ch, Tr, Alloc>:: basic_format(const string_type& s)
+        : style_(0), cur_arg_(0), num_args_(0), dumped_(false),
+          exceptions_(io::all_error_bits)
+    {
+        parse(s);  
+    }
+
+    template< class Ch, class Tr, class Alloc> // just don't copy the buf_ member
+    basic_format<Ch, Tr, Alloc>:: basic_format(const basic_format& x)
+        : items_(x.items_), bound_(x.bound_), style_(x.style_),
+          cur_arg_(x.cur_arg_), num_args_(x.num_args_), dumped_(x.dumped_),
+          prefix_(x.prefix_), exceptions_(x.exceptions_), loc_(x.loc_)
+    {
+    }
+
+    template< class Ch, class Tr, class Alloc>  // just don't copy the buf_ member
+    basic_format<Ch, Tr, Alloc>& basic_format<Ch, Tr, Alloc>:: 
+    operator= (const basic_format& x) {
+        if(this == &x)
+            return *this;
+        (basic_format<Ch, Tr, Alloc>(x)).swap(*this);
+        return *this;
+    }
+    template< class Ch, class Tr, class Alloc>
+    void  basic_format<Ch, Tr, Alloc>:: 
+    swap (basic_format & x) {
+        std::swap(exceptions_, x.exceptions_);
+        std::swap(style_, x.style_); 
+        std::swap(cur_arg_, x.cur_arg_); 
+        std::swap(num_args_, x.num_args_);
+        std::swap(dumped_, x.dumped_);
+
+        items_.swap(x.items_);
+        prefix_.swap(x.prefix_);
+        bound_.swap(x.bound_);
+    }
+
+    template< class Ch, class Tr, class Alloc>
+    unsigned char basic_format<Ch,Tr, Alloc>:: exceptions() const {
+        return exceptions_; 
+    }
+
+    template< class Ch, class Tr, class Alloc>
+    unsigned char basic_format<Ch,Tr, Alloc>:: exceptions(unsigned char newexcept) { 
+        unsigned char swp = exceptions_; 
+        exceptions_ = newexcept; 
+        return swp; 
+    }
+
+    template<class Ch, class Tr, class Alloc>
+    void basic_format<Ch, Tr, Alloc>:: 
+    make_or_reuse_data (std::size_t nbitems) {
+#if !defined(BOOST_NO_STD_LOCALE)
+        Ch fill = ( BOOST_USE_FACET(std::ctype<Ch>, getloc()) ). widen(' ');
+#else
+        Ch fill = ' ';
+#endif
+        if(items_.size() == 0)
+            items_.assign( nbitems, format_item_t(fill) );
+        else {
+            if(nbitems>items_.size())
+                items_.resize(nbitems, format_item_t(fill));
+            bound_.resize(0);
+            for(std::size_t i=0; i < nbitems; ++i)
+                items_[i].reset(fill); //  strings are resized, instead of reallocated
+        }
+        prefix_.resize(0);
+    }
+
+    template< class Ch, class Tr, class Alloc>
+    basic_format<Ch,Tr, Alloc>& basic_format<Ch,Tr, Alloc>:: 
+    clear () {
+        // empty the string buffers (except bound arguments)
+        // and make the format object ready for formatting a new set of arguments
+
+        BOOST_ASSERT( bound_.size()==0 || num_args_ == static_cast<int>(bound_.size()) );
+
+        for(unsigned long i=0; i<items_.size(); ++i) {
+            // clear converted strings only if the corresponding argument is not  bound :
+            if( bound_.size()==0 || items_[i].argN_<0 || !bound_[ items_[i].argN_ ] )
+                items_[i].res_.resize(0);
+        }
+        cur_arg_=0; dumped_=false;
+        // maybe first arg is bound:
+        if(bound_.size() != 0) {
+            for(; cur_arg_ < num_args_ && bound_[cur_arg_]; ++cur_arg_)
+                {}
+        }
+        return *this;
+    }
+
+    template< class Ch, class Tr, class Alloc>
+    basic_format<Ch,Tr, Alloc>& basic_format<Ch,Tr, Alloc>:: 
+    clear_binds () {
+        // remove all binds, then clear()
+        bound_.resize(0);
+        clear();
+        return *this;
+    }
+
+    template< class Ch, class Tr, class Alloc>
+    basic_format<Ch,Tr, Alloc>& basic_format<Ch,Tr, Alloc>:: 
+    clear_bind (int argN) {
+        // remove the bind of ONE argument then clear()
+        if(argN<1 || argN > num_args_ || bound_.size()==0 || !bound_[argN-1] ) {
+            if( exceptions() & io::out_of_range_bit)
+                boost::throw_exception(io::out_of_range(argN, 1, num_args_+1 ) ); 
+            else return *this;
+        }
+        bound_[argN-1]=false;
+        clear();
+        return *this;
+    }
+
+    template< class Ch, class Tr, class Alloc>
+    int basic_format<Ch,Tr, Alloc>::
+    bound_args() const {
+        if(bound_.size()==0)
+            return 0;
+        int n=0;
+        for(int i=0; i<num_args_ ; ++i)
+            if(bound_[i])
+                ++n;
+        return n;
+    }
+
+    template< class Ch, class Tr, class Alloc>
+    int basic_format<Ch,Tr, Alloc>::
+    fed_args() const {
+        if(bound_.size()==0)
+            return cur_arg_;
+        int n=0;
+        for(int i=0; i<cur_arg_ ; ++i)
+            if(!bound_[i])
+                ++n;
+        return n;
+    }
+
+    template< class Ch, class Tr, class Alloc>
+    int basic_format<Ch,Tr, Alloc>::
+    cur_arg() const {
+      return cur_arg_+1; }
+
+    template< class Ch, class Tr, class Alloc>
+    int basic_format<Ch,Tr, Alloc>::
+    remaining_args() const {
+        if(bound_.size()==0)
+            return num_args_-cur_arg_;
+        int n=0;
+        for(int i=cur_arg_; i<num_args_ ; ++i)
+            if(!bound_[i])
+                ++n;
+        return n;
+    }
+
+    template< class Ch, class Tr, class Alloc>
+    typename basic_format<Ch, Tr, Alloc>::string_type 
+    basic_format<Ch,Tr, Alloc>:: 
+    str () const {
+        if(items_.size()==0)
+            return prefix_;
+        if( cur_arg_ < num_args_)
+            if( exceptions() & io::too_few_args_bit )
+                // not enough variables supplied
+                boost::throw_exception(io::too_few_args(cur_arg_, num_args_)); 
+
+        unsigned long i;
+        string_type res;
+        res.reserve(size());
+        res += prefix_;
+        for(i=0; i < items_.size(); ++i) {
+            const format_item_t& item = items_[i];
+            res += item.res_;
+            if( item.argN_ == format_item_t::argN_tabulation) { 
+                BOOST_ASSERT( item.pad_scheme_ & format_item_t::tabulation);
+                if( static_cast<size_type>(item.fmtstate_.width_) > res.size() )
+                    res.append( static_cast<size_type>(item.fmtstate_.width_) - res.size(),
+                                        item.fmtstate_.fill_ );
+            }
+            res += item.appendix_;
+        }
+        dumped_=true;
+        return res;
+    }
+    template< class Ch, class Tr, class Alloc>
+    typename std::basic_string<Ch, Tr, Alloc>::size_type  basic_format<Ch,Tr, Alloc>:: 
+    size () const {
+#ifdef BOOST_MSVC
+       // If std::min<unsigned> or std::max<unsigned> are already instantiated
+       // at this point then we get a blizzard of warning messages when we call
+       // those templates with std::size_t as arguments.  Weird and very annoyning...
+#pragma warning(push)
+#pragma warning(disable:4267)
+#endif
+        BOOST_USING_STD_MAX();
+        size_type sz = prefix_.size();
+        unsigned long i;
+        for(i=0; i < items_.size(); ++i) {
+            const format_item_t& item = items_[i];
+            sz += item.res_.size();
+            if( item.argN_ == format_item_t::argN_tabulation)
+                sz = max BOOST_PREVENT_MACRO_SUBSTITUTION (sz,
+                                        static_cast<size_type>(item.fmtstate_.width_) );
+            sz += item.appendix_.size();
+        }
+        return sz;
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+    }
+
+namespace io {
+namespace detail {
+
+    template<class Ch, class Tr, class Alloc, class T> 
+    basic_format<Ch, Tr, Alloc>&  
+    bind_arg_body (basic_format<Ch, Tr, Alloc>& self, int argN, const T& val) {
+        // bind one argument to a fixed value
+        // this is persistent over clear() calls, thus also over str() and <<
+        if(self.dumped_) 
+            self.clear(); // needed because we will modify cur_arg_
+        if(argN<1 || argN > self.num_args_) {
+            if( self.exceptions() & io::out_of_range_bit )
+                boost::throw_exception(io::out_of_range(argN, 1, self.num_args_+1 ) );
+            else return self;
+        }
+        if(self.bound_.size()==0) 
+            self.bound_.assign(self.num_args_,false);
+        else 
+            BOOST_ASSERT( self.num_args_ == static_cast<signed int>(self.bound_.size()) );
+        int o_cur_arg = self.cur_arg_;
+        self.cur_arg_ = argN-1; // arrays begin at 0
+
+        self.bound_[self.cur_arg_]=false; // if already set, we unset and re-sets..
+        self.operator%(val); // put val at the right place, because cur_arg is set
+    
+
+        // Now re-position cur_arg before leaving :
+        self.cur_arg_ = o_cur_arg; 
+        self.bound_[argN-1]=true;
+        if(self.cur_arg_ == argN-1 ) {
+            // hum, now this arg is bound, so move to next free arg
+            while(self.cur_arg_ < self.num_args_ && self.bound_[self.cur_arg_])   
+                ++self.cur_arg_;
+        }
+        // In any case, we either have all args, or are on an unbound arg :
+        BOOST_ASSERT( self.cur_arg_ >= self.num_args_ || ! self.bound_[self.cur_arg_]);
+        return self;
+    }
+
+    template<class Ch, class Tr, class Alloc, class T> basic_format<Ch, Tr, Alloc>&
+    modify_item_body (basic_format<Ch, Tr, Alloc>& self, int itemN, T manipulator) {
+        // applies a manipulator to the format_item describing a given directive.
+        // this is a permanent change, clear or reset won't cancel that.
+        if(itemN<1 || itemN > static_cast<signed int>(self.items_.size() )) {
+            if( self.exceptions() & io::out_of_range_bit ) 
+                boost::throw_exception(io::out_of_range(itemN, 1, static_cast<int>(self.items_.size()) ));
+            else return self;
+        }
+        self.items_[itemN-1].fmtstate_. template apply_manip<T> ( manipulator );
+        return self;
+    }
+
+} // namespace detail
+} // namespace io
+} // namespace boost
+
+
+
+#endif  // BOOST_FORMAT_IMPLEMENTATION_HPP
diff --git a/include/boost/format/free_funcs.hpp b/include/boost/format/free_funcs.hpp
new file mode 100644
index 0000000..3a51545
--- /dev/null
+++ b/include/boost/format/free_funcs.hpp
@@ -0,0 +1,70 @@
+// ----------------------------------------------------------------------------
+// free_funcs.hpp :  implementation of the free functions of boost::format
+// ----------------------------------------------------------------------------
+
+//  Copyright Samuel Krempp 2003. 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)
+
+//  See http://www.boost.org/libs/format for library home page
+
+// ----------------------------------------------------------------------------
+
+#ifndef BOOST_FORMAT_FUNCS_HPP
+#define BOOST_FORMAT_FUNCS_HPP
+
+#include <boost/format/format_class.hpp>
+#include <boost/throw_exception.hpp>
+
+namespace boost {
+
+    template<class Ch, class Tr, class Alloc> inline 
+    std::basic_string<Ch, Tr, Alloc> str(const basic_format<Ch, Tr, Alloc>& f) {
+        // adds up all pieces of strings and converted items, and return the formatted string
+        return f.str();
+    }
+    namespace io {
+         using ::boost::str; // keep compatibility with when it was defined in this N.S.
+    }   // - namespace io
+
+#ifndef  BOOST_NO_TEMPLATE_STD_STREAM
+        template<class Ch, class Tr, class Alloc>
+        std::basic_ostream<Ch, Tr> & 
+        operator<<( std::basic_ostream<Ch, Tr> & os,
+                    const basic_format<Ch, Tr, Alloc>& f)
+#else
+        template<class Ch, class Tr, class Alloc>
+        std::ostream & 
+        operator<<( std::ostream & os,
+                    const basic_format<Ch, Tr, Alloc>& f)
+#endif
+        // effect: "return os << str(f);" but we can do it faster
+    {
+        typedef boost::basic_format<Ch, Tr, Alloc>   format_t;
+        if(f.items_.size()==0) 
+            os << f.prefix_;
+        else {
+            if(f.cur_arg_ < f.num_args_)
+                if( f.exceptions() & io::too_few_args_bit )
+                    // not enough variables supplied
+                    boost::throw_exception(io::too_few_args(f.cur_arg_, f.num_args_)); 
+            if(f.style_ & format_t::special_needs) 
+                os << f.str();
+            else {
+                // else we dont have to count chars output, so we dump directly to os :
+                os << f.prefix_;
+                for(unsigned long i=0; i<f.items_.size(); ++i) {
+                    const typename format_t::format_item_t& item = f.items_[i];
+                    os << item.res_;
+                    os << item.appendix_;
+                }
+            }
+        }
+        f.dumped_=true;
+        return os;
+    }
+
+} // namespace boost
+
+
+#endif // BOOST_FORMAT_FUNCS_HPP
diff --git a/include/boost/format/group.hpp b/include/boost/format/group.hpp
new file mode 100644
index 0000000..c586b2a
--- /dev/null
+++ b/include/boost/format/group.hpp
@@ -0,0 +1,684 @@
+
+// ----------------------------------------------------------------------------
+// group.hpp :  encapsulates a group of manipulators along with an argument
+// ----------------------------------------------------------------------------
+
+//  Copyright Samuel Krempp 2003. 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)
+
+//  See http://www.boost.org/libs/format for library home page
+
+// ----------------------------------------------------------------------------
+
+                      
+// group_head : cut the last element of a group out.
+// (is overloaded below on each type of group)
+
+// group_last : returns the last element of a group
+// (is overloaded below on each type of group)
+// ----------------------------------------------------------------------------
+
+
+#ifndef BOOST_FORMAT_GROUP_HPP
+#define BOOST_FORMAT_GROUP_HPP
+
+#include <boost/config.hpp>
+
+
+namespace boost {
+namespace io {
+
+
+namespace detail {
+
+
+// empty group, but useful even though.
+struct group0 
+{
+    group0()      {}
+};
+
+template <class Ch, class Tr>
+inline
+BOOST_IO_STD basic_ostream<Ch, Tr>&
+operator << ( BOOST_IO_STD basic_ostream<Ch, Tr>& os,
+             const group0& )
+{ 
+   return os; 
+}
+
+template <class T1>
+struct group1
+{
+    T1 a1_;
+    group1(T1 a1)
+      : a1_(a1)
+      {}
+private:
+   group1& operator=(const group1&);
+};
+
+template <class Ch, class Tr, class T1>
+inline
+BOOST_IO_STD basic_ostream<Ch, Tr>&
+operator << (BOOST_IO_STD basic_ostream<Ch, Tr>& os,
+             const group1<T1>& x)
+{ 
+   os << x.a1_;  
+   return os; 
+}
+
+
+
+
+template <class T1,class T2>
+struct group2
+{
+    T1 a1_;
+    T2 a2_;
+    group2(T1 a1,T2 a2)
+      : a1_(a1),a2_(a2)
+      {}
+private:
+   group2& operator=(const group2&);
+};
+
+template <class Ch, class Tr, class T1,class T2>
+inline
+BOOST_IO_STD basic_ostream<Ch, Tr>&
+operator << (BOOST_IO_STD basic_ostream<Ch, Tr>& os,
+             const group2<T1,T2>& x)
+{ 
+   os << x.a1_<< x.a2_;  
+   return os; 
+}
+
+template <class T1,class T2,class T3>
+struct group3
+{
+    T1 a1_;
+    T2 a2_;
+    T3 a3_;
+    group3(T1 a1,T2 a2,T3 a3)
+      : a1_(a1),a2_(a2),a3_(a3)
+      {}
+private:
+   group3& operator=(const group3&);
+};
+
+template <class Ch, class Tr, class T1,class T2,class T3>
+inline
+BOOST_IO_STD basic_ostream<Ch, Tr>&
+operator << (BOOST_IO_STD basic_ostream<Ch, Tr>& os,
+             const group3<T1,T2,T3>& x)
+{ 
+   os << x.a1_<< x.a2_<< x.a3_;  
+   return os; 
+}
+
+template <class T1,class T2,class T3,class T4>
+struct group4
+{
+    T1 a1_;
+    T2 a2_;
+    T3 a3_;
+    T4 a4_;
+    group4(T1 a1,T2 a2,T3 a3,T4 a4)
+      : a1_(a1),a2_(a2),a3_(a3),a4_(a4)
+      {}
+private:
+   group4& operator=(const group4&);
+};
+
+template <class Ch, class Tr, class T1,class T2,class T3,class T4>
+inline
+BOOST_IO_STD basic_ostream<Ch, Tr>&
+operator << (BOOST_IO_STD basic_ostream<Ch, Tr>& os,
+             const group4<T1,T2,T3,T4>& x)
+{ 
+   os << x.a1_<< x.a2_<< x.a3_<< x.a4_;  
+   return os; 
+}
+
+template <class T1,class T2,class T3,class T4,class T5>
+struct group5
+{
+    T1 a1_;
+    T2 a2_;
+    T3 a3_;
+    T4 a4_;
+    T5 a5_;
+    group5(T1 a1,T2 a2,T3 a3,T4 a4,T5 a5)
+      : a1_(a1),a2_(a2),a3_(a3),a4_(a4),a5_(a5)
+      {}
+};
+
+template <class Ch, class Tr, class T1,class T2,class T3,class T4,class T5>
+inline
+BOOST_IO_STD basic_ostream<Ch, Tr>&
+operator << (BOOST_IO_STD basic_ostream<Ch, Tr>& os,
+             const group5<T1,T2,T3,T4,T5>& x)
+{ 
+   os << x.a1_<< x.a2_<< x.a3_<< x.a4_<< x.a5_;  
+   return os; 
+}
+
+template <class T1,class T2,class T3,class T4,class T5,class T6>
+struct group6
+{
+    T1 a1_;
+    T2 a2_;
+    T3 a3_;
+    T4 a4_;
+    T5 a5_;
+    T6 a6_;
+    group6(T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6)
+      : a1_(a1),a2_(a2),a3_(a3),a4_(a4),a5_(a5),a6_(a6)
+      {}
+};
+
+template <class Ch, class Tr, class T1,class T2,class T3,class T4,class T5,class T6>
+inline
+BOOST_IO_STD basic_ostream<Ch, Tr>&
+operator << (BOOST_IO_STD basic_ostream<Ch, Tr>& os,
+             const group6<T1,T2,T3,T4,T5,T6>& x)
+{ 
+   os << x.a1_<< x.a2_<< x.a3_<< x.a4_<< x.a5_<< x.a6_;  
+   return os; 
+}
+
+template <class T1,class T2,class T3,class T4,class T5,class T6,class T7>
+struct group7
+{
+    T1 a1_;
+    T2 a2_;
+    T3 a3_;
+    T4 a4_;
+    T5 a5_;
+    T6 a6_;
+    T7 a7_;
+    group7(T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6,T7 a7)
+      : a1_(a1),a2_(a2),a3_(a3),a4_(a4),a5_(a5),a6_(a6),a7_(a7)
+      {}
+};
+
+template <class Ch, class Tr, class T1,class T2,class T3,class T4,class T5,class T6,class T7>
+inline
+BOOST_IO_STD basic_ostream<Ch, Tr>&
+operator << (BOOST_IO_STD basic_ostream<Ch, Tr>& os,
+             const group7<T1,T2,T3,T4,T5,T6,T7>& x)
+{ 
+   os << x.a1_<< x.a2_<< x.a3_<< x.a4_<< x.a5_<< x.a6_<< x.a7_;  
+   return os; 
+}
+
+template <class T1,class T2,class T3,class T4,class T5,class T6,class T7,class T8>
+struct group8
+{
+    T1 a1_;
+    T2 a2_;
+    T3 a3_;
+    T4 a4_;
+    T5 a5_;
+    T6 a6_;
+    T7 a7_;
+    T8 a8_;
+    group8(T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6,T7 a7,T8 a8)
+      : a1_(a1),a2_(a2),a3_(a3),a4_(a4),a5_(a5),a6_(a6),a7_(a7),a8_(a8)
+      {}
+};
+
+template <class Ch, class Tr, class T1,class T2,class T3,class T4,class T5,class T6,class T7,class T8>
+inline
+BOOST_IO_STD basic_ostream<Ch, Tr>&
+operator << (BOOST_IO_STD basic_ostream<Ch, Tr>& os,
+             const group8<T1,T2,T3,T4,T5,T6,T7,T8>& x)
+{ 
+   os << x.a1_<< x.a2_<< x.a3_<< x.a4_<< x.a5_<< x.a6_<< x.a7_<< x.a8_;  
+   return os; 
+}
+
+template <class T1,class T2,class T3,class T4,class T5,class T6,class T7,class T8,class T9>
+struct group9
+{
+    T1 a1_;
+    T2 a2_;
+    T3 a3_;
+    T4 a4_;
+    T5 a5_;
+    T6 a6_;
+    T7 a7_;
+    T8 a8_;
+    T9 a9_;
+    group9(T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6,T7 a7,T8 a8,T9 a9)
+      : a1_(a1),a2_(a2),a3_(a3),a4_(a4),a5_(a5),a6_(a6),a7_(a7),a8_(a8),a9_(a9)
+      {}
+};
+
+template <class Ch, class Tr, class T1,class T2,class T3,class T4,class T5,class T6,class T7,class T8,class T9>
+inline
+BOOST_IO_STD basic_ostream<Ch, Tr>&
+operator << (BOOST_IO_STD basic_ostream<Ch, Tr>& os,
+             const group9<T1,T2,T3,T4,T5,T6,T7,T8,T9>& x)
+{ 
+   os << x.a1_<< x.a2_<< x.a3_<< x.a4_<< x.a5_<< x.a6_<< x.a7_<< x.a8_<< x.a9_;  
+   return os; 
+}
+
+template <class T1,class T2,class T3,class T4,class T5,class T6,class T7,class T8,class T9,class T10>
+struct group10
+{
+    T1 a1_;
+    T2 a2_;
+    T3 a3_;
+    T4 a4_;
+    T5 a5_;
+    T6 a6_;
+    T7 a7_;
+    T8 a8_;
+    T9 a9_;
+    T10 a10_;
+    group10(T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6,T7 a7,T8 a8,T9 a9,T10 a10)
+      : a1_(a1),a2_(a2),a3_(a3),a4_(a4),a5_(a5),a6_(a6),a7_(a7),a8_(a8),a9_(a9),a10_(a10)
+      {}
+};
+
+template <class Ch, class Tr, class T1,class T2,class T3,class T4,class T5,class T6,class T7,class T8,class T9,class T10>
+inline
+BOOST_IO_STD basic_ostream<Ch, Tr>&
+operator << (BOOST_IO_STD basic_ostream<Ch, Tr>& os,
+             const group10<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10>& x)
+{ 
+   os << x.a1_<< x.a2_<< x.a3_<< x.a4_<< x.a5_<< x.a6_<< x.a7_<< x.a8_<< x.a9_<< x.a10_;  
+   return os; 
+}
+
+
+
+
+template <class T1,class T2>
+inline
+group1<T1> 
+group_head( group2<T1,T2> const& x)
+{
+   return group1<T1> (x.a1_); 
+}
+
+template <class T1,class T2>
+inline
+group1<T2> 
+group_last( group2<T1,T2> const& x)
+{
+   return group1<T2> (x.a2_); 
+}
+
+
+
+template <class T1,class T2,class T3>
+inline
+group2<T1,T2> 
+group_head( group3<T1,T2,T3> const& x)
+{
+   return group2<T1,T2> (x.a1_,x.a2_); 
+}
+
+template <class T1,class T2,class T3>
+inline
+group1<T3> 
+group_last( group3<T1,T2,T3> const& x)
+{
+   return group1<T3> (x.a3_); 
+}
+
+
+
+template <class T1,class T2,class T3,class T4>
+inline
+group3<T1,T2,T3> 
+group_head( group4<T1,T2,T3,T4> const& x)
+{
+   return group3<T1,T2,T3> (x.a1_,x.a2_,x.a3_); 
+}
+
+template <class T1,class T2,class T3,class T4>
+inline
+group1<T4> 
+group_last( group4<T1,T2,T3,T4> const& x)
+{
+   return group1<T4> (x.a4_); 
+}
+
+
+
+template <class T1,class T2,class T3,class T4,class T5>
+inline
+group4<T1,T2,T3,T4> 
+group_head( group5<T1,T2,T3,T4,T5> const& x)
+{
+   return group4<T1,T2,T3,T4> (x.a1_,x.a2_,x.a3_,x.a4_); 
+}
+
+template <class T1,class T2,class T3,class T4,class T5>
+inline
+group1<T5> 
+group_last( group5<T1,T2,T3,T4,T5> const& x)
+{
+   return group1<T5> (x.a5_); 
+}
+
+
+
+template <class T1,class T2,class T3,class T4,class T5,class T6>
+inline
+group5<T1,T2,T3,T4,T5> 
+group_head( group6<T1,T2,T3,T4,T5,T6> const& x)
+{
+   return group5<T1,T2,T3,T4,T5> (x.a1_,x.a2_,x.a3_,x.a4_,x.a5_); 
+}
+
+template <class T1,class T2,class T3,class T4,class T5,class T6>
+inline
+group1<T6> 
+group_last( group6<T1,T2,T3,T4,T5,T6> const& x)
+{
+   return group1<T6> (x.a6_); 
+}
+
+
+
+template <class T1,class T2,class T3,class T4,class T5,class T6,class T7>
+inline
+group6<T1,T2,T3,T4,T5,T6> 
+group_head( group7<T1,T2,T3,T4,T5,T6,T7> const& x)
+{
+   return group6<T1,T2,T3,T4,T5,T6> (x.a1_,x.a2_,x.a3_,x.a4_,x.a5_,x.a6_); 
+}
+
+template <class T1,class T2,class T3,class T4,class T5,class T6,class T7>
+inline
+group1<T7> 
+group_last( group7<T1,T2,T3,T4,T5,T6,T7> const& x)
+{
+   return group1<T7> (x.a7_); 
+}
+
+
+
+template <class T1,class T2,class T3,class T4,class T5,class T6,class T7,class T8>
+inline
+group7<T1,T2,T3,T4,T5,T6,T7> 
+group_head( group8<T1,T2,T3,T4,T5,T6,T7,T8> const& x)
+{
+   return group7<T1,T2,T3,T4,T5,T6,T7> (x.a1_,x.a2_,x.a3_,x.a4_,x.a5_,x.a6_,x.a7_); 
+}
+
+template <class T1,class T2,class T3,class T4,class T5,class T6,class T7,class T8>
+inline
+group1<T8> 
+group_last( group8<T1,T2,T3,T4,T5,T6,T7,T8> const& x)
+{
+   return group1<T8> (x.a8_); 
+}
+
+
+
+template <class T1,class T2,class T3,class T4,class T5,class T6,class T7,class T8,class T9>
+inline
+group8<T1,T2,T3,T4,T5,T6,T7,T8> 
+group_head( group9<T1,T2,T3,T4,T5,T6,T7,T8,T9> const& x)
+{
+   return group8<T1,T2,T3,T4,T5,T6,T7,T8> (x.a1_,x.a2_,x.a3_,x.a4_,x.a5_,x.a6_,x.a7_,x.a8_); 
+}
+
+template <class T1,class T2,class T3,class T4,class T5,class T6,class T7,class T8,class T9>
+inline
+group1<T9> 
+group_last( group9<T1,T2,T3,T4,T5,T6,T7,T8,T9> const& x)
+{
+   return group1<T9> (x.a9_); 
+}
+
+
+
+template <class T1,class T2,class T3,class T4,class T5,class T6,class T7,class T8,class T9,class T10>
+inline
+group9<T1,T2,T3,T4,T5,T6,T7,T8,T9> 
+group_head( group10<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10> const& x)
+{
+   return group9<T1,T2,T3,T4,T5,T6,T7,T8,T9> (x.a1_,x.a2_,x.a3_,x.a4_,x.a5_,x.a6_,x.a7_,x.a8_,x.a9_); 
+}
+
+template <class T1,class T2,class T3,class T4,class T5,class T6,class T7,class T8,class T9,class T10>
+inline
+group1<T10> 
+group_last( group10<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10> const& x)
+{
+   return group1<T10> (x.a10_); 
+}
+
+
+
+
+
+} // namespace detail
+
+
+
+// helper functions
+
+
+inline detail::group1< detail::group0 >  
+group() { return detail::group1< detail::group0 > ( detail::group0() ); }
+
+template  <class T1, class Var> 
+inline
+detail::group1< detail::group2<T1, Var const&> >
+  group(T1 a1, Var const& var)
+{ 
+   return detail::group1< detail::group2<T1, Var const&> >
+                   ( detail::group2<T1, Var const&> 
+                        (a1, var) 
+                  );
+}
+
+template  <class T1,class T2, class Var> 
+inline
+detail::group1< detail::group3<T1,T2, Var const&> >
+  group(T1 a1,T2 a2, Var const& var)
+{ 
+   return detail::group1< detail::group3<T1,T2, Var const&> >
+                   ( detail::group3<T1,T2, Var const&> 
+                        (a1,a2, var) 
+                  );
+}
+
+template  <class T1,class T2,class T3, class Var> 
+inline
+detail::group1< detail::group4<T1,T2,T3, Var const&> >
+  group(T1 a1,T2 a2,T3 a3, Var const& var)
+{ 
+   return detail::group1< detail::group4<T1,T2,T3, Var const&> >
+                   ( detail::group4<T1,T2,T3, Var const&> 
+                        (a1,a2,a3, var) 
+                  );
+}
+
+template  <class T1,class T2,class T3,class T4, class Var> 
+inline
+detail::group1< detail::group5<T1,T2,T3,T4, Var const&> >
+  group(T1 a1,T2 a2,T3 a3,T4 a4, Var const& var)
+{ 
+   return detail::group1< detail::group5<T1,T2,T3,T4, Var const&> >
+                   ( detail::group5<T1,T2,T3,T4, Var const&> 
+                        (a1,a2,a3,a4, var) 
+                  );
+}
+
+template  <class T1,class T2,class T3,class T4,class T5, class Var> 
+inline
+detail::group1< detail::group6<T1,T2,T3,T4,T5, Var const&> >
+  group(T1 a1,T2 a2,T3 a3,T4 a4,T5 a5, Var const& var)
+{ 
+   return detail::group1< detail::group6<T1,T2,T3,T4,T5, Var const&> >
+                   ( detail::group6<T1,T2,T3,T4,T5, Var const&> 
+                        (a1,a2,a3,a4,a5, var) 
+                  );
+}
+
+template  <class T1,class T2,class T3,class T4,class T5,class T6, class Var> 
+inline
+detail::group1< detail::group7<T1,T2,T3,T4,T5,T6, Var const&> >
+  group(T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6, Var const& var)
+{ 
+   return detail::group1< detail::group7<T1,T2,T3,T4,T5,T6, Var const&> >
+                   ( detail::group7<T1,T2,T3,T4,T5,T6, Var const&> 
+                        (a1,a2,a3,a4,a5,a6, var) 
+                  );
+}
+
+template  <class T1,class T2,class T3,class T4,class T5,class T6,class T7, class Var> 
+inline
+detail::group1< detail::group8<T1,T2,T3,T4,T5,T6,T7, Var const&> >
+  group(T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6,T7 a7, Var const& var)
+{ 
+   return detail::group1< detail::group8<T1,T2,T3,T4,T5,T6,T7, Var const&> >
+                   ( detail::group8<T1,T2,T3,T4,T5,T6,T7, Var const&> 
+                        (a1,a2,a3,a4,a5,a6,a7, var) 
+                  );
+}
+
+template  <class T1,class T2,class T3,class T4,class T5,class T6,class T7,class T8, class Var> 
+inline
+detail::group1< detail::group9<T1,T2,T3,T4,T5,T6,T7,T8, Var const&> >
+  group(T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6,T7 a7,T8 a8, Var const& var)
+{ 
+   return detail::group1< detail::group9<T1,T2,T3,T4,T5,T6,T7,T8, Var const&> >
+                   ( detail::group9<T1,T2,T3,T4,T5,T6,T7,T8, Var const&> 
+                        (a1,a2,a3,a4,a5,a6,a7,a8, var) 
+                  );
+}
+
+template  <class T1,class T2,class T3,class T4,class T5,class T6,class T7,class T8,class T9, class Var> 
+inline
+detail::group1< detail::group10<T1,T2,T3,T4,T5,T6,T7,T8,T9, Var const&> >
+  group(T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6,T7 a7,T8 a8,T9 a9, Var const& var)
+{ 
+   return detail::group1< detail::group10<T1,T2,T3,T4,T5,T6,T7,T8,T9, Var const&> >
+                   ( detail::group10<T1,T2,T3,T4,T5,T6,T7,T8,T9, Var const&> 
+                        (a1,a2,a3,a4,a5,a6,a7,a8,a9, var) 
+                  );
+}
+
+
+#ifndef BOOST_NO_OVERLOAD_FOR_NON_CONST
+
+template  <class T1, class Var> 
+inline
+detail::group1< detail::group2<T1, Var&> >
+  group(T1 a1, Var& var)
+{ 
+   return detail::group1< detail::group2<T1, Var&> >
+                   ( detail::group2<T1, Var&> 
+                        (a1, var) 
+                  );
+}
+
+template  <class T1,class T2, class Var> 
+inline
+detail::group1< detail::group3<T1,T2, Var&> >
+  group(T1 a1,T2 a2, Var& var)
+{ 
+   return detail::group1< detail::group3<T1,T2, Var&> >
+                   ( detail::group3<T1,T2, Var&> 
+                        (a1,a2, var) 
+                  );
+}
+
+template  <class T1,class T2,class T3, class Var> 
+inline
+detail::group1< detail::group4<T1,T2,T3, Var&> >
+  group(T1 a1,T2 a2,T3 a3, Var& var)
+{ 
+   return detail::group1< detail::group4<T1,T2,T3, Var&> >
+                   ( detail::group4<T1,T2,T3, Var&> 
+                        (a1,a2,a3, var) 
+                  );
+}
+
+template  <class T1,class T2,class T3,class T4, class Var> 
+inline
+detail::group1< detail::group5<T1,T2,T3,T4, Var&> >
+  group(T1 a1,T2 a2,T3 a3,T4 a4, Var& var)
+{ 
+   return detail::group1< detail::group5<T1,T2,T3,T4, Var&> >
+                   ( detail::group5<T1,T2,T3,T4, Var&> 
+                        (a1,a2,a3,a4, var) 
+                  );
+}
+
+template  <class T1,class T2,class T3,class T4,class T5, class Var> 
+inline
+detail::group1< detail::group6<T1,T2,T3,T4,T5, Var&> >
+  group(T1 a1,T2 a2,T3 a3,T4 a4,T5 a5, Var& var)
+{ 
+   return detail::group1< detail::group6<T1,T2,T3,T4,T5, Var&> >
+                   ( detail::group6<T1,T2,T3,T4,T5, Var&> 
+                        (a1,a2,a3,a4,a5, var) 
+                  );
+}
+
+template  <class T1,class T2,class T3,class T4,class T5,class T6, class Var> 
+inline
+detail::group1< detail::group7<T1,T2,T3,T4,T5,T6, Var&> >
+  group(T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6, Var& var)
+{ 
+   return detail::group1< detail::group7<T1,T2,T3,T4,T5,T6, Var&> >
+                   ( detail::group7<T1,T2,T3,T4,T5,T6, Var&> 
+                        (a1,a2,a3,a4,a5,a6, var) 
+                  );
+}
+
+template  <class T1,class T2,class T3,class T4,class T5,class T6,class T7, class Var> 
+inline
+detail::group1< detail::group8<T1,T2,T3,T4,T5,T6,T7, Var&> >
+  group(T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6,T7 a7, Var& var)
+{ 
+   return detail::group1< detail::group8<T1,T2,T3,T4,T5,T6,T7, Var&> >
+                   ( detail::group8<T1,T2,T3,T4,T5,T6,T7, Var&> 
+                        (a1,a2,a3,a4,a5,a6,a7, var) 
+                  );
+}
+
+template  <class T1,class T2,class T3,class T4,class T5,class T6,class T7,class T8, class Var> 
+inline
+detail::group1< detail::group9<T1,T2,T3,T4,T5,T6,T7,T8, Var&> >
+  group(T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6,T7 a7,T8 a8, Var& var)
+{ 
+   return detail::group1< detail::group9<T1,T2,T3,T4,T5,T6,T7,T8, Var&> >
+                   ( detail::group9<T1,T2,T3,T4,T5,T6,T7,T8, Var&> 
+                        (a1,a2,a3,a4,a5,a6,a7,a8, var) 
+                  );
+}
+
+template  <class T1,class T2,class T3,class T4,class T5,class T6,class T7,class T8,class T9, class Var> 
+inline
+detail::group1< detail::group10<T1,T2,T3,T4,T5,T6,T7,T8,T9, Var&> >
+  group(T1 a1,T2 a2,T3 a3,T4 a4,T5 a5,T6 a6,T7 a7,T8 a8,T9 a9, Var& var)
+{ 
+   return detail::group1< detail::group10<T1,T2,T3,T4,T5,T6,T7,T8,T9, Var&> >
+                   ( detail::group10<T1,T2,T3,T4,T5,T6,T7,T8,T9, Var&> 
+                        (a1,a2,a3,a4,a5,a6,a7,a8,a9, var) 
+                  );
+}
+
+
+#endif  // - BOOST_NO_OVERLOAD_FOR_NON_CONST
+
+
+} // namespace io
+
+} // namespace boost
+
+
+#endif   // BOOST_FORMAT_GROUP_HPP
diff --git a/include/boost/format/internals.hpp b/include/boost/format/internals.hpp
new file mode 100644
index 0000000..cd5fc54
--- /dev/null
+++ b/include/boost/format/internals.hpp
@@ -0,0 +1,203 @@
+// ----------------------------------------------------------------------------
+// internals.hpp :  internal structs : stream_format_state, format_item. 
+//                  included by format.hpp
+// ----------------------------------------------------------------------------
+
+//  Copyright Samuel Krempp 2003. 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)
+
+//  See http://www.boost.org/libs/format for library home page
+
+// ----------------------------------------------------------------------------
+
+#ifndef BOOST_FORMAT_INTERNALS_HPP
+#define BOOST_FORMAT_INTERNALS_HPP
+
+
+#include <string>
+#include <boost/assert.hpp>
+#include <boost/core/ignore_unused.hpp>
+#include <boost/optional.hpp>
+#include <boost/limits.hpp>
+#include <boost/format/detail/compat_workarounds.hpp>
+#include <boost/format/alt_sstream.hpp> // used as a dummy stream
+
+namespace boost {
+namespace io {
+namespace detail {
+
+
+//---- stream_format_state --------------------------------------------------//
+
+//   set of params that define the format state of a stream
+    template<class Ch, class Tr> 
+    struct stream_format_state 
+    {
+        typedef BOOST_IO_STD basic_ios<Ch, Tr>   basic_ios;
+
+        stream_format_state(Ch fill)                 { reset(fill); }
+//        stream_format_state(const basic_ios& os)     { set_by_stream(os); }
+
+        void reset(Ch fill);                     //- sets to default state.
+        void set_by_stream(const basic_ios& os); //- sets to os's state.
+        void apply_on(basic_ios & os,            //- applies format_state to the stream
+                      boost::io::detail::locale_t * loc_default = 0) const;
+        template<class T> 
+        void apply_manip(T manipulator)          //- modifies state by applying manipulator
+            { apply_manip_body<Ch, Tr, T>( *this, manipulator) ; }
+
+        // --- data ---
+        std::streamsize width_;
+        std::streamsize precision_;
+        Ch fill_; 
+        std::ios_base::fmtflags flags_;
+        std::ios_base::iostate  rdstate_;
+        std::ios_base::iostate  exceptions_;
+        boost::optional<boost::io::detail::locale_t>  loc_;
+    };  
+
+
+//---- format_item  ---------------------------------------------------------//
+
+//   stores all parameters that can be specified in format strings
+    template<class Ch, class Tr, class Alloc>  
+    struct format_item 
+    {     
+        enum pad_values { zeropad = 1, spacepad =2, centered=4, tabulation = 8 };
+                         // 1. if zeropad is set, all other bits are not, 
+                         // 2. if tabulation is set, all others are not.
+                         // centered and spacepad can be mixed freely.
+        enum arg_values { argN_no_posit   = -1, // non-positional directive. will set argN later
+                          argN_tabulation = -2, // tabulation directive. (no argument read) 
+                          argN_ignored    = -3  // ignored directive. (no argument read)
+        };
+        typedef BOOST_IO_STD basic_ios<Ch, Tr>                    basic_ios;
+        typedef detail::stream_format_state<Ch, Tr>               stream_format_state;
+        typedef ::std::basic_string<Ch, Tr, Alloc>                string_type;
+
+        format_item(Ch fill) :argN_(argN_no_posit), fmtstate_(fill), 
+                              truncate_(max_streamsize()), pad_scheme_(0)  {}
+        void reset(Ch fill);
+        void compute_states(); // sets states  according to truncate and pad_scheme.
+
+        static std::streamsize max_streamsize() { 
+            return (std::numeric_limits<std::streamsize>::max)();
+        }
+
+        // --- data ---
+        int         argN_;  //- argument number (starts at 0,  eg : %1 => argN=0)
+                            //  negative values for items that don't process an argument
+        string_type  res_;      //- result of the formatting of this item
+        string_type  appendix_; //- piece of string between this item and the next
+
+        stream_format_state fmtstate_;// set by parsing, is only affected by modify_item
+
+        std::streamsize truncate_;//- is set for directives like %.5s that ask truncation
+        unsigned int pad_scheme_;//- several possible padding schemes can mix. see pad_values
+    }; 
+
+
+
+//--- Definitions  ------------------------------------------------------------
+
+// -   stream_format_state:: -------------------------------------------------
+    template<class Ch, class Tr>
+    void stream_format_state<Ch,Tr>:: apply_on (basic_ios & os,
+                      boost::io::detail::locale_t * loc_default) const {
+    // If a locale is available, set it first. "os.fill(fill_);" may chrash otherwise. 
+#if !defined(BOOST_NO_STD_LOCALE)
+        if(loc_)
+            os.imbue(loc_.get());
+        else if(loc_default)
+            os.imbue(*loc_default);
+#else
+        ignore_unused(loc_default);
+#endif        
+        // set the state of this stream according to our params
+        if(width_ != -1)
+            os.width(width_);
+        if(precision_ != -1)
+            os.precision(precision_);
+        if(fill_ != 0)
+            os.fill(fill_);
+        os.flags(flags_);
+        os.clear(rdstate_);
+        os.exceptions(exceptions_);
+    }
+
+    template<class Ch, class Tr>
+    void stream_format_state<Ch,Tr>:: set_by_stream(const basic_ios& os) {
+        // set our params according to the state of this stream
+        flags_ = os.flags();
+        width_ = os.width();
+        precision_ = os.precision();
+        fill_ = os.fill();
+        rdstate_ = os.rdstate();
+        exceptions_ = os.exceptions();
+    }
+
+
+    template<class Ch, class Tr, class T>
+    void apply_manip_body( stream_format_state<Ch, Tr>& self,
+                           T manipulator) {
+        // modify our params according to the manipulator
+        basic_oaltstringstream<Ch, Tr>  ss;
+        self.apply_on( ss );
+        ss << manipulator;
+        self.set_by_stream( ss );
+    }
+
+    template<class Ch, class Tr> inline
+    void stream_format_state<Ch,Tr>:: reset(Ch fill) {
+        // set our params to standard's default state.   cf 27.4.4.1 of the C++ norm
+        width_=0; precision_=6; 
+        fill_=fill; // default is widen(' '), but we cant compute it without the locale
+        flags_ = std::ios_base::dec | std::ios_base::skipws; 
+        // the adjust_field part is left equal to 0, which means right.
+        exceptions_ = std::ios_base::goodbit;
+        rdstate_ = std::ios_base::goodbit;
+    }
+
+
+// ---   format_item:: --------------------------------------------------------
+
+    template<class Ch, class Tr, class Alloc> 
+    void format_item<Ch, Tr, Alloc>:: 
+    reset (Ch fill) { 
+        argN_=argN_no_posit; truncate_ = max_streamsize(); pad_scheme_ =0; 
+        res_.resize(0); appendix_.resize(0);
+        fmtstate_.reset(fill);
+    }
+
+    template<class Ch, class Tr, class Alloc> 
+    void format_item<Ch, Tr, Alloc>:: 
+    compute_states() {
+        // reflect pad_scheme_   on  fmt_state_
+        //   because some pad_schemes has complex consequences on several state params.
+        if(pad_scheme_ & zeropad) {
+            // ignore zeropad in left alignment :
+            if(fmtstate_.flags_ & std::ios_base::left) {
+              BOOST_ASSERT(!(fmtstate_.flags_ &(std::ios_base::adjustfield ^std::ios_base::left)));
+              // only left bit might be set. (not right, nor internal)
+              pad_scheme_ = pad_scheme_ & (~zeropad); 
+            }
+            else { 
+                pad_scheme_ &= ~spacepad; // printf ignores spacepad when zeropadding
+                fmtstate_.fill_='0'; 
+                fmtstate_.flags_ = (fmtstate_.flags_ & ~std::ios_base::adjustfield) 
+                    | std::ios_base::internal;
+                // removes all adjustfield bits, and adds internal.
+            }
+        }
+        if(pad_scheme_ & spacepad) {
+            if(fmtstate_.flags_ & std::ios_base::showpos)
+                pad_scheme_ &= ~spacepad;
+        }
+    }
+
+
+} } } // namespaces boost :: io :: detail
+
+
+#endif // BOOST_FORMAT_INTERNALS_HPP
diff --git a/include/boost/format/internals_fwd.hpp b/include/boost/format/internals_fwd.hpp
new file mode 100644
index 0000000..18cf122
--- /dev/null
+++ b/include/boost/format/internals_fwd.hpp
@@ -0,0 +1,64 @@
+// ----------------------------------------------------------------------------
+// internals_fwd.hpp :  forward declarations, for internal headers
+// ----------------------------------------------------------------------------
+
+//  Copyright Samuel Krempp 2003. 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)
+
+//  See http://www.boost.org/libs/format for library home page
+
+// ----------------------------------------------------------------------------
+
+#ifndef BOOST_FORMAT_INTERNAL_FWD_HPP
+#define BOOST_FORMAT_INTERNAL_FWD_HPP
+
+#include <boost/format/format_fwd.hpp>
+#include <boost/config.hpp>
+
+
+namespace boost {
+namespace io {
+
+namespace detail {
+  template<class Ch, class Tr> struct stream_format_state;
+    template<class Ch, class Tr, class Alloc> struct format_item;
+
+
+  // these functions were intended as methods, 
+  // but MSVC have problems with template member functions :
+  // defined in format_implementation.hpp :
+    template<class Ch, class Tr, class Alloc, class T> 
+    basic_format<Ch, Tr, Alloc>&  
+    modify_item_body (basic_format<Ch, Tr, Alloc>& self, 
+                      int itemN, T manipulator);
+
+    template<class Ch, class Tr, class Alloc, class T> 
+    basic_format<Ch, Tr, Alloc>&  
+    bind_arg_body (basic_format<Ch, Tr, Alloc>& self,
+                   int argN, const T& val);
+
+    // in internals.hpp :
+    template<class Ch, class Tr, class T> 
+    void apply_manip_body (stream_format_state<Ch, Tr>& self,
+                           T manipulator);
+
+    // argument feeding (defined in feed_args.hpp ) :
+    template<class Ch, class Tr, class Alloc, class T> 
+    void distribute (basic_format<Ch,Tr, Alloc>& self, T x);
+
+    template<class Ch, class Tr, class Alloc, class T> 
+    basic_format<Ch, Tr, Alloc>& 
+    feed (basic_format<Ch,Tr, Alloc>& self, T x);
+
+    template<class Ch, class Tr, class Alloc, class T> 
+    basic_format<Ch, Tr, Alloc>& 
+    feed_impl (basic_format<Ch,Tr, Alloc>& self, T x);
+ 
+} // namespace detail
+
+} // namespace io
+} // namespace boost
+
+
+#endif //  BOOST_FORMAT_INTERNAL_FWD_HPP
diff --git a/include/boost/format/parsing.hpp b/include/boost/format/parsing.hpp
new file mode 100644
index 0000000..0007492
--- /dev/null
+++ b/include/boost/format/parsing.hpp
@@ -0,0 +1,564 @@
+// ----------------------------------------------------------------------------
+// parsing.hpp :  implementation of the parsing member functions
+//                      ( parse, parse_printf_directive)
+// ----------------------------------------------------------------------------
+
+//  Copyright Samuel Krempp 2003. 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)
+
+// see http://www.boost.org/libs/format for library home page
+
+// ----------------------------------------------------------------------------
+
+#ifndef BOOST_FORMAT_PARSING_HPP
+#define BOOST_FORMAT_PARSING_HPP
+
+
+#include <boost/format/format_class.hpp>
+#include <boost/format/exceptions.hpp>
+#include <boost/throw_exception.hpp>
+#include <boost/assert.hpp>
+#include <boost/config.hpp>
+#include <boost/core/ignore_unused.hpp>
+
+namespace boost {
+namespace io {
+namespace detail {
+
+#if defined(BOOST_NO_STD_LOCALE)
+    // streams will be used for narrow / widen. but these methods are not const
+    template<class T>
+    T& const_or_not(const T& x) {
+        return const_cast<T&> (x);
+    }
+#else
+    template<class T>
+    const T& const_or_not(const T& x) {
+        return x;
+    }
+#endif
+
+    template<class Ch, class Facet> inline
+    char wrap_narrow(const Facet& fac, Ch c, char deflt) {
+        return const_or_not(fac).narrow(c, deflt);
+    }
+
+    template<class Ch, class Facet> inline
+    bool wrap_isdigit(const Facet& fac, Ch c) {
+#if ! defined( BOOST_NO_LOCALE_ISDIGIT )
+        return fac.is(std::ctype<Ch>::digit, c);
+# else
+        ignore_unused(fac);
+        using namespace std;
+        return isdigit(c) != 0;
+#endif
+    }
+
+    template<class Iter, class Facet>
+    Iter wrap_scan_notdigit(const Facet & fac, Iter beg, Iter end) {
+        using namespace std;
+        for( ; beg!=end && wrap_isdigit(fac, *beg); ++beg) ;
+        return beg;
+    }
+
+
+    // Input : [start, last) iterators range and a
+    //          a Facet to use its widen/narrow member function
+    // Effects : read sequence and convert digits into integral n, of type Res
+    // Returns : n
+    template<class Res, class Iter, class Facet>
+    Iter str2int (const Iter & start, const Iter & last, Res & res,
+                 const Facet& fac)
+    {
+        using namespace std;
+        Iter it;
+        res=0;
+        for(it=start; it != last && wrap_isdigit(fac, *it); ++it ) {
+            char cur_ch = wrap_narrow(fac, *it, 0); // cant fail.
+            res *= 10;
+            res += cur_ch - '0'; // 22.2.1.1.2.13 of the C++ standard
+        }
+        return it;
+    }
+
+    // auxiliary func called by parse_printf_directive
+    // for centralising error handling
+    // it either throws if user sets the corresponding flag, or does nothing.
+    inline void maybe_throw_exception(unsigned char exceptions,
+                                      std::size_t pos, std::size_t size)
+    {
+        if(exceptions & io::bad_format_string_bit)
+            boost::throw_exception(io::bad_format_string(pos, size) );
+    }
+
+
+    // Input: the position of a printf-directive in the format-string
+    //    a basic_ios& merely to use its widen/narrow member function
+    //    a bitset'exceptions' telling whether to throw exceptions on errors.
+    // Returns:
+    //  true if parse succeeded (ignore some errors if exceptions disabled)
+    //  false if it failed so bad that the directive should be printed verbatim
+    // Effects:
+    //  start is incremented so that *start is the first char after
+    //     this directive
+    //  *fpar is set with the parameters read in the directive
+    template<class Ch, class Tr, class Alloc, class Iter, class Facet>
+    bool parse_printf_directive(Iter & start, const Iter& last,
+                                detail::format_item<Ch, Tr, Alloc> * fpar,
+                                const Facet& fac,
+                                std::size_t offset, unsigned char exceptions)
+    {
+        typedef typename basic_format<Ch, Tr, Alloc>::format_item_t format_item_t;
+
+        fpar->argN_ = format_item_t::argN_no_posit;  // if no positional-directive
+        bool precision_set = false;
+        bool in_brackets=false;
+        Iter start0 = start;
+        std::size_t fstring_size = last-start0+offset;
+        char mssiz = 0;
+
+        if(start>= last) { // empty directive : this is a trailing %
+                maybe_throw_exception(exceptions, start-start0 + offset, fstring_size);
+                return false;
+        }
+
+        if(*start== const_or_not(fac).widen( '|')) {
+            in_brackets=true;
+            if( ++start >= last ) {
+                maybe_throw_exception(exceptions, start-start0 + offset, fstring_size);
+                return false;
+            }
+        }
+
+        // the flag '0' would be picked as a digit for argument order, but here it's a flag :
+        if(*start== const_or_not(fac).widen( '0'))
+            goto parse_flags;
+
+        // handle argument order (%2$d)  or possibly width specification: %2d
+        if(wrap_isdigit(fac, *start)) {
+            int n;
+            start = str2int(start, last, n, fac);
+            if( start >= last ) {
+                maybe_throw_exception(exceptions, start-start0+offset, fstring_size);
+                return false;
+            }
+
+            // %N% case : this is already the end of the directive
+            if( *start ==  const_or_not(fac).widen( '%') ) {
+                fpar->argN_ = n-1;
+                ++start;
+                if( in_brackets)
+                    maybe_throw_exception(exceptions, start-start0+offset, fstring_size);
+                return true;
+            }
+
+            if ( *start== const_or_not(fac).widen( '$') ) {
+                fpar->argN_ = n-1;
+                ++start;
+            }
+            else {
+                // non-positional directive
+                fpar->fmtstate_.width_ = n;
+                fpar->argN_  = format_item_t::argN_no_posit;
+                goto parse_precision;
+            }
+        }
+
+      parse_flags:
+        // handle flags
+        while (start != last) { // as long as char is one of + - = _ # 0 or ' '
+            switch ( wrap_narrow(fac, *start, 0)) {
+                case '\'':
+                    break; // no effect yet. (painful to implement)
+                case '-':
+                    fpar->fmtstate_.flags_ |= std::ios_base::left;
+                    break;
+                case '=':
+                    fpar->pad_scheme_ |= format_item_t::centered;
+                    break;
+                case '_':
+                    fpar->fmtstate_.flags_ |= std::ios_base::internal;
+                    break;
+                case ' ':
+                    fpar->pad_scheme_ |= format_item_t::spacepad;
+                    break;
+                case '+':
+                    fpar->fmtstate_.flags_ |= std::ios_base::showpos;
+                    break;
+                case '0':
+                    fpar->pad_scheme_ |= format_item_t::zeropad;
+                    // need to know alignment before really setting flags,
+                    // so just add 'zeropad' flag for now, it will be processed later.
+                    break;
+                case '#':
+                    fpar->fmtstate_.flags_ |= std::ios_base::showpoint | std::ios_base::showbase;
+                    break;
+                default:
+                    goto parse_width;
+            }
+            ++start;
+        } // loop on flag.
+
+        if( start>=last) {
+            maybe_throw_exception(exceptions, start-start0+offset, fstring_size);
+            return true;
+        }
+
+      // first skip 'asterisk fields' : * or num (length)
+      parse_width:
+        if(*start == const_or_not(fac).widen( '*') )
+            ++start;
+        else if(start!=last && wrap_isdigit(fac, *start))
+            start = str2int(start, last, fpar->fmtstate_.width_, fac);
+
+      parse_precision:
+        if( start>= last) {
+            maybe_throw_exception(exceptions, start-start0+offset, fstring_size);
+            return true;
+        }
+        // handle precision spec
+        if (*start== const_or_not(fac).widen( '.')) {
+            ++start;
+            if(start != last && *start == const_or_not(fac).widen( '*') )
+                ++start;
+            else if(start != last && wrap_isdigit(fac, *start)) {
+                start = str2int(start, last, fpar->fmtstate_.precision_, fac);
+                precision_set = true;
+            }
+            else
+                fpar->fmtstate_.precision_ =0;
+        }
+
+      // argument type modifiers
+        while (start != last) {
+            switch (wrap_narrow(fac, *start, 0)) {
+                case 'h':
+                case 'l':
+                case 'j':
+                case 'z':
+                case 'L':
+                    // boost::format ignores argument type modifiers as it relies on
+                    // the type of the argument fed into it by operator %
+                    break;
+
+                // Note that the ptrdiff_t argument type 't' from C++11 is not honored
+                // because it was already in use as the tabulation specifier in boost::format
+                // case 't':
+
+                // Microsoft extensions:
+                // https://msdn.microsoft.com/en-us/library/tcxf1dw6.aspx
+
+                case 'w':
+                    break;
+                case 'I':
+                    mssiz = 'I';
+                    break;
+                case '3':
+                    if (mssiz != 'I') {
+                        maybe_throw_exception(exceptions, start - start0 + offset, fstring_size);
+                        return true;
+                    }
+                    mssiz = '3';
+                    break;
+                case '2':
+                    if (mssiz != '3') {
+                        maybe_throw_exception(exceptions, start - start0 + offset, fstring_size);
+                        return true;
+                    }
+                    mssiz = 0x00;
+                    break;
+                case '6':
+                    if (mssiz != 'I') {
+                        maybe_throw_exception(exceptions, start - start0 + offset, fstring_size);
+                        return true;
+                    }
+                    mssiz = '6';
+                    break;
+                case '4':
+                    if (mssiz != '6') {
+                        maybe_throw_exception(exceptions, start - start0 + offset, fstring_size);
+                        return true;
+                    }
+                    mssiz = 0x00;
+                    break;
+                default:
+                    if (mssiz && mssiz == 'I') {
+                        mssiz = 0;
+                    }
+                    goto parse_conversion_specification;
+            }
+            ++start;
+        } // loop on argument type modifiers to pick up 'hh', 'll', and the more complex microsoft ones
+
+      parse_conversion_specification:
+        if (start >= last || mssiz) {
+            maybe_throw_exception(exceptions, start - start0 + offset, fstring_size);
+            return true;
+        }
+
+        if( in_brackets && *start== const_or_not(fac).widen( '|') ) {
+            ++start;
+            return true;
+        }
+
+        // The default flags are "dec" and "skipws"
+        // so if changing the base, need to unset basefield first
+
+        switch (wrap_narrow(fac, *start, 0))
+        {
+            // Boolean
+            case 'b':
+                fpar->fmtstate_.flags_ |= std::ios_base::boolalpha;
+                break;
+
+            // Decimal
+            case 'u':
+            case 'd':
+            case 'i':
+                // Defaults are sufficient
+                break;
+
+            // Hex
+            case 'X':
+                fpar->fmtstate_.flags_ |= std::ios_base::uppercase;
+                BOOST_FALLTHROUGH;
+            case 'x':
+            case 'p': // pointer => set hex.
+                fpar->fmtstate_.flags_ &= ~std::ios_base::basefield;
+                fpar->fmtstate_.flags_ |= std::ios_base::hex;
+                break;
+
+            // Octal
+            case 'o':
+                fpar->fmtstate_.flags_ &= ~std::ios_base::basefield;
+                fpar->fmtstate_.flags_ |= std::ios_base::oct;
+                break;
+
+            // Floating
+            case 'A':
+                fpar->fmtstate_.flags_ |= std::ios_base::uppercase;
+                BOOST_FALLTHROUGH;
+            case 'a':
+                fpar->fmtstate_.flags_ &= ~std::ios_base::basefield;
+                fpar->fmtstate_.flags_ |= std::ios_base::fixed;
+                fpar->fmtstate_.flags_ |= std::ios_base::scientific;
+                break;
+            case 'E':
+                fpar->fmtstate_.flags_ |= std::ios_base::uppercase;
+                BOOST_FALLTHROUGH;
+            case 'e':
+                fpar->fmtstate_.flags_ |= std::ios_base::scientific;
+                break;
+            case 'F':
+                fpar->fmtstate_.flags_ |= std::ios_base::uppercase;
+                BOOST_FALLTHROUGH;
+            case 'f':
+                fpar->fmtstate_.flags_ |= std::ios_base::fixed;
+                break;
+            case 'G':
+                fpar->fmtstate_.flags_ |= std::ios_base::uppercase;
+                BOOST_FALLTHROUGH;
+            case 'g':
+                // default flags are correct here
+                break;
+
+            // Tabulation (a boost::format extension)
+            case 'T':
+                ++start;
+                if( start >= last) {
+                    maybe_throw_exception(exceptions, start-start0+offset, fstring_size);
+                    return false;
+                } else {
+                    fpar->fmtstate_.fill_ = *start;
+                }
+                fpar->pad_scheme_ |= format_item_t::tabulation;
+                fpar->argN_ = format_item_t::argN_tabulation;
+                break;
+            case 't':
+                fpar->fmtstate_.fill_ = const_or_not(fac).widen( ' ');
+                fpar->pad_scheme_ |= format_item_t::tabulation;
+                fpar->argN_ = format_item_t::argN_tabulation;
+                break;
+
+            // Character
+            case 'C':
+            case 'c':
+                fpar->truncate_ = 1;
+                break;
+
+            // String
+            case 'S':
+            case 's':
+                if(precision_set) // handle truncation manually, with own parameter.
+                    fpar->truncate_ = fpar->fmtstate_.precision_;
+                fpar->fmtstate_.precision_ = 6; // default stream precision.
+                break;
+
+            // %n is insecure and ignored by boost::format
+            case 'n' :
+                fpar->argN_ = format_item_t::argN_ignored;
+                break;
+
+            default:
+                maybe_throw_exception(exceptions, start-start0+offset, fstring_size);
+        }
+        ++start;
+
+        if( in_brackets ) {
+            if( start != last && *start== const_or_not(fac).widen( '|') ) {
+                ++start;
+                return true;
+            }
+            else  maybe_throw_exception(exceptions, start-start0+offset, fstring_size);
+        }
+        return true;
+    }
+    // -end parse_printf_directive()
+
+    template<class String, class Facet>
+    int upper_bound_from_fstring(const String& buf,
+                                 const typename String::value_type arg_mark,
+                                 const Facet& fac,
+                                 unsigned char exceptions)
+    {
+        // quick-parsing of the format-string to count arguments mark (arg_mark, '%')
+        // returns : upper bound on the number of format items in the format strings
+        using namespace boost::io;
+        typename String::size_type i1=0;
+        int num_items=0;
+        while( (i1=buf.find(arg_mark,i1)) != String::npos ) {
+            if( i1+1 >= buf.size() ) {
+                if(exceptions & bad_format_string_bit)
+                    boost::throw_exception(bad_format_string(i1, buf.size() )); // must not end in ".. %"
+                else {
+                  ++num_items;
+                  break;
+                }
+            }
+            if(buf[i1+1] == buf[i1] ) {// escaped "%%"
+                i1+=2; continue;
+            }
+
+            ++i1;
+            // in case of %N% directives, dont count it double (wastes allocations..) :
+            i1 = detail::wrap_scan_notdigit(fac, buf.begin()+i1, buf.end()) - buf.begin();
+            if( i1 < buf.size() && buf[i1] == arg_mark )
+                ++i1;
+            ++num_items;
+        }
+        return num_items;
+    }
+    template<class String> inline
+    void append_string(String& dst, const String& src,
+                       const typename String::size_type beg,
+                       const typename String::size_type end) {
+        dst.append(src.begin()+beg, src.begin()+end);
+    }
+
+} // detail namespace
+} // io namespace
+
+
+
+// -----------------------------------------------
+//  format :: parse(..)
+
+    template<class Ch, class Tr, class Alloc>
+    basic_format<Ch, Tr, Alloc>& basic_format<Ch, Tr, Alloc>::
+    parse (const string_type& buf) {
+        // parse the format-string
+        using namespace std;
+#if !defined(BOOST_NO_STD_LOCALE)
+        const std::ctype<Ch> & fac = BOOST_USE_FACET( std::ctype<Ch>, getloc());
+#else
+        io::basic_oaltstringstream<Ch, Tr, Alloc> fac;
+        //has widen and narrow even on compilers without locale
+#endif
+
+        const Ch arg_mark = io::detail::const_or_not(fac).widen( '%');
+        bool ordered_args=true;
+        int max_argN=-1;
+
+        // A: find upper_bound on num_items and allocates arrays
+        int num_items = io::detail::upper_bound_from_fstring(buf, arg_mark, fac, exceptions());
+        make_or_reuse_data(num_items);
+
+        // B: Now the real parsing of the format string :
+        num_items=0;
+        typename string_type::size_type i0=0, i1=0;
+        typename string_type::const_iterator it;
+        bool special_things=false;
+        int cur_item=0;
+        while( (i1=buf.find(arg_mark,i1)) != string_type::npos ) {
+            string_type & piece = (cur_item==0) ? prefix_ : items_[cur_item-1].appendix_;
+            if( buf[i1+1] == buf[i1] ) { // escaped mark, '%%'
+                io::detail::append_string(piece, buf, i0, i1+1);
+                i1+=2; i0=i1;
+                continue;
+            }
+            BOOST_ASSERT(  static_cast<unsigned int>(cur_item) < items_.size() || cur_item==0);
+
+            if(i1!=i0) {
+                io::detail::append_string(piece, buf, i0, i1);
+                i0=i1;
+            }
+            ++i1;
+            it = buf.begin()+i1;
+            bool parse_ok = io::detail::parse_printf_directive(
+                it, buf.end(), &items_[cur_item], fac, i1, exceptions());
+            i1 = it - buf.begin();
+            if( ! parse_ok ) // the directive will be printed verbatim
+                continue;
+            i0=i1;
+            items_[cur_item].compute_states(); // process complex options, like zeropad, into params
+
+            int argN=items_[cur_item].argN_;
+            if(argN == format_item_t::argN_ignored)
+                continue;
+            if(argN ==format_item_t::argN_no_posit)
+                ordered_args=false;
+            else if(argN == format_item_t::argN_tabulation) special_things=true;
+            else if(argN > max_argN) max_argN = argN;
+            ++num_items;
+            ++cur_item;
+        } // loop on %'s
+        BOOST_ASSERT(cur_item == num_items);
+
+        // store the final piece of string
+        {
+            string_type & piece = (cur_item==0) ? prefix_ : items_[cur_item-1].appendix_;
+            io::detail::append_string(piece, buf, i0, buf.size());
+        }
+
+        if( !ordered_args) {
+            if(max_argN >= 0 ) {  // dont mix positional with non-positionnal directives
+                if(exceptions() & io::bad_format_string_bit)
+                    boost::throw_exception(
+                        io::bad_format_string(static_cast<std::size_t>(max_argN), 0));
+                // else do nothing. => positionnal arguments are processed as non-positionnal
+            }
+            // set things like it would have been with positional directives :
+            int non_ordered_items = 0;
+            for(int i=0; i< num_items; ++i)
+                if(items_[i].argN_ == format_item_t::argN_no_posit) {
+                    items_[i].argN_ = non_ordered_items;
+                    ++non_ordered_items;
+                }
+            max_argN = non_ordered_items-1;
+        }
+
+        // C: set some member data :
+        items_.resize(num_items, format_item_t(io::detail::const_or_not(fac).widen( ' ')) );
+
+        if(special_things) style_ |= special_needs;
+        num_args_ = max_argN + 1;
+        if(ordered_args) style_ |=  ordered;
+        else style_ &= ~ordered;
+        return *this;
+    }
+
+} // namespace boost
+
+
+#endif //  BOOST_FORMAT_PARSING_HPP
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..52cd354
--- /dev/null
+++ b/index.html
@@ -0,0 +1,132 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<html>
+<head>
+  <meta http-equiv="Content-Language" content="en-us">
+  <meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
+
+  <title>The Boost Format library</title>
+</head>
+
+<body bgcolor="#FFFFFF" text="#000000">
+  <table border="1" bgcolor="#007F7F" cellpadding="2" summary="">
+    <tr>
+      <td bgcolor="#FFFFFF"><img src="../../boost.png" alt=
+      "boost.png (6897 bytes)" width="277" height="86"></td>
+
+      <td><a href="../../index.htm"><font face="Arial" color=
+      "#FFFFFF"><big>Home</big></font></a></td>
+
+      <td><a href="../libraries.htm"><font face="Arial" color=
+      "#FFFFFF"><big>Libraries</big></font></a></td>
+
+      <td><a href="http://www.boost.org/people/people.htm"><font face="Arial" color=
+      "#FFFFFF"><big>People</big></font></a></td>
+
+      <td><a href="http://www.boost.org/more/faq.htm"><font face="Arial" color=
+      "#FFFFFF"><big>FAQ</big></font></a></td>
+
+      <td><a href="../../more/index.htm"><font face="Arial" color=
+      "#FFFFFF"><big>More</big></font></a></td>
+    </tr>
+  </table>
+
+  <h1>Boost Format library</h1>
+
+  <p>The format library provides a class for formatting arguments according
+  to a format-string, as does printf, but with two major differences
+  :<br></p>
+
+  <ul>
+    <li>format sends the arguments to an internal stream, and so is entirely
+    type-safe and naturally supports all user-defined types.</li>
+
+    <li>The ellipsis (...) can not be used correctly in the strongly typed
+    context of format, and thus the function call with arbitrary arguments is
+    replaced by successive calls to an <i>argument feeding</i>
+    <b>operator%</b></li>
+  </ul>
+
+  <p><br>
+  You can find more Details in :</p>
+
+  <ul>
+    <li><a href="doc/format.html">Documentation</a> (HTML).</li>
+
+    <li>Headers
+
+      <ul>
+        <li><a href="../../boost/format.hpp">format.hpp</a> : user
+        frontend.</li>
+
+        <li><a href="../../boost/format/format_fwd.hpp">format_fwd.hpp</a> :
+        user forward declarations.</li>
+
+        <li><a href=
+        "../../boost/format/format_class.hpp">format_class.hpp</a> : the
+        class interface</li>
+
+        <li><a href=
+        "../../boost/format/format_implementation.hpp">format_implementation.hpp</a>:
+        implementation of the member functions</li>
+
+        <li><a href="../../boost/format/feed_args.hpp">feed_args.hpp</a> :
+        argument feeding helper functions</li>
+
+        <li><a href="../../boost/format/free_funcs.hpp">free_funcs.hpp</a> :
+        free functions definitions</li>
+
+        <li><a href="../../boost/format/parsing.hpp">parsing.hpp</a> : code
+        for parsing format-strings</li>
+
+        <li><a href="../../boost/format/group.hpp">group.hpp</a> : auxiliary
+        struct used to group arguments and manipulators</li>
+
+        <li><a href="../../boost/format/exceptions.hpp">exceptions.hpp</a> :
+        exceptions used by the library</li>
+
+        <li><a href="../../boost/format/internals.hpp">internals.hpp</a> :
+        auxiliary structs stream_format_state and format_item</li>
+      </ul>
+    </li>
+
+    <li>Sample programs
+
+      <ul>
+        <li>The program <a href=
+        "./example/sample_formats.cpp">sample_formats.cpp</a> demonstrates
+        simple uses of <b>format</b>.</li>
+
+        <li><a href=
+        "./example/sample_new_features.cpp">sample_new_features.cpp</a>
+        illustrates the few formatting features that were added to printf's
+        syntax such as simple positional directives, centered alignment, and
+        'tabulations'.</li>
+
+        <li><a href="./example/sample_advanced.cpp">sample_advanced.cpp</a>
+        demonstrates uses of advanced features, like reusing, and modifying,
+        format objects, etc..</li>
+
+        <li>And <a href=
+        "./example/sample_userType.cpp">sample_userType.cpp</a> shows the
+        behaviour of the <b>format</b> library on user-defined types.</li>
+      </ul>
+    </li>
+  </ul>
+  <hr>
+
+  <p><a href="http://validator.w3.org/check?uri=referer"><img border="0" src=
+  "../../doc/images/valid-html401.png" alt="Valid HTML 4.01 Transitional"
+  height="31" width="88"></a></p>
+
+  <p>Revised 
+  <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->02 December, 2006<!--webbot bot="Timestamp" endspan i-checksum="38510" --></p>
+
+  <p><i>Copyright &copy; 2003 Samuel Krempp</i></p>
+
+  <p><i>Distributed under the Boost Software License, Version 1.0. (See
+  accompanying file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or
+  copy at <a href=
+  "http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>)</i></p>
+</body>
+</html>
diff --git a/meta/libraries.json b/meta/libraries.json
new file mode 100644
index 0000000..22fe8c2
--- /dev/null
+++ b/meta/libraries.json
@@ -0,0 +1,16 @@
+{
+    "key": "format",
+    "name": "Format",
+    "authors": [
+        "Samuel Krempp"
+    ],
+    "description": "The format library provides a type-safe mechanism for formatting arguments according to a printf-like format-string.",
+    "category": [
+        "IO",
+        "String"
+    ],
+    "maintainers": [
+        "Samuel Krempp <krempp -at- crans.ens-cachan.fr>",
+        "James E. King III <jking -at- apache.org>"
+    ]
+}
diff --git a/test/Jamfile.v2 b/test/Jamfile.v2
new file mode 100644
index 0000000..f77f97c
--- /dev/null
+++ b/test/Jamfile.v2
@@ -0,0 +1,20 @@
+#  Boost.Format Library test Jamfile
+#
+#  Copyright (c) 2003 Samuel Krempp
+#
+#  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)
+
+import testing ;
+
+test-suite "format"
+   :    [ run format_test1.cpp ]
+        [ run format_test1.cpp : : : <toolset>msvc:<cxxflags>"/FIWindows.h" : format_test1_windows_h ]
+        [ run format_test2.cpp ]
+        [ run format_test2.cpp : : : <toolset>msvc:<cxxflags>"/FIWindows.h" : format_test2_windows_h ]
+        [ run format_test3.cpp ]
+        [ run format_test3.cpp : : : <toolset>msvc:<cxxflags>"/FIWindows.h" : format_test3_windows_h ]
+        [ run format_test_enum.cpp : : : <toolset>clang:<cxxflags>-Wno-unnamed-type-template-args ]
+        [ run format_test_exceptions.cpp ]
+        [ run format_test_wstring.cpp ]
+   ;
\ No newline at end of file
diff --git a/test/format_test1.cpp b/test/format_test1.cpp
new file mode 100644
index 0000000..d259d23
--- /dev/null
+++ b/test/format_test1.cpp
@@ -0,0 +1,42 @@
+// ------------------------------------------------------------------------------
+// libs/format/test/format_test1.cpp :  test constructing objects and basic parsing
+// ------------------------------------------------------------------------------
+
+//  Copyright Samuel Krempp 2003. 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)
+
+//  See http://www.boost.org/libs/format for library home page
+
+// ------------------------------------------------------------------------------
+
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/format.hpp>
+
+int main(int, char* [])
+{
+  using boost::format;
+  using boost::str;
+
+  if(str( format("  %%  ") ) != "  %  ")
+      BOOST_ERROR("Basic parsing without arguments Failed");
+  if(str( format("nothing") ) != "nothing")
+      BOOST_ERROR("Basic parsing without arguments Failed");
+  if(str( format("%%  ") ) != "%  ")
+      BOOST_ERROR("Basic parsing without arguments Failed");
+  if(str( format("  %%") ) != "  %")
+      BOOST_ERROR("Basic parsing without arguments Failed");
+  if(str( format("  %n  ") ) != "    ")
+      BOOST_ERROR("Basic parsing without arguments Failed");
+  if(str( format("%n  ") ) != "  ")
+      BOOST_ERROR("Basic parsing without arguments Failed");
+  if(str( format("  %n") ) != "  ")
+      BOOST_ERROR("Basic parsing without arguments Failed");
+
+  if(str( format("%%##%%##%%1 %1%00") % "Escaped OK" ) != "%##%##%1 Escaped OK00")
+      BOOST_ERROR("Basic parsing Failed");
+  if(str( format("%%##%#x ##%%1 %s00") % 20 % "Escaped OK" ) != "%##0x14 ##%1 Escaped OK00")
+      BOOST_ERROR("Basic p-parsing Failed") ;
+
+  return boost::report_errors();
+}
diff --git a/test/format_test2.cpp b/test/format_test2.cpp
new file mode 100644
index 0000000..9fb0610
--- /dev/null
+++ b/test/format_test2.cpp
@@ -0,0 +1,212 @@
+// ------------------------------------------------------------------------------
+// format_test2.cpp :  a few real, simple tests.
+// ------------------------------------------------------------------------------
+
+//  Copyright Samuel Krempp 2003. 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)
+
+// see http://www.boost.org/libs/format for library home page
+
+// ------------------------------------------------------------------------------
+
+#include <boost/algorithm/string.hpp>
+#include <boost/config.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/format.hpp>
+#include <boost/predef.h>
+
+#include <iostream>
+#include <iomanip>
+
+#if !defined(BOOST_NO_STD_LOCALE)
+#include <locale>
+#endif
+
+struct Rational {
+  int n,d;
+  Rational (int an, int ad) : n(an), d(ad) {}
+};
+
+std::ostream& operator<<( std::ostream& os, const Rational& r) {
+  os << r.n << "/" << r.d;
+  return os;
+}
+
+#if !defined(BOOST_NO_STD_LOCALE)
+// in C++03 this has to be globally defined or gcc complains
+struct custom_tf : std::numpunct<char> {
+    std::string do_truename()  const { return "POSITIVE"; }
+    std::string do_falsename() const { return "NEGATIVE"; }
+};
+#endif
+
+int main(int, char* [])
+{
+    using namespace std;
+    using boost::format;
+    using boost::io::group;
+    using boost::str;
+
+    Rational r(16,9);
+    const Rational cr(9,16);
+
+    string s;
+    s = str(format("%5%. %5$=6s . %1% format %5%, c'%3% %1% %2%.\n")
+            % "le" % "bonheur" % "est" % "trop" % group(setfill('_'), "bref") );
+
+    if(s  != "bref. _bref_ . le format bref, c'est le bonheur.\n") {
+      cerr << s;
+      BOOST_ERROR("centered alignement : formatting result incorrect");
+    }
+
+
+    s = str(format("%+8d %-8d\n") % r % cr );
+    if(s  != "  +16/+9 9/16    \n") {
+      cerr << s;
+      BOOST_ERROR("(user-type) formatting result incorrect");
+    }
+
+    s = str(format("[%0+4d %0+8d %-08d]\n") % 8 % r % r);
+    if(s  != "[+008 +0016/+9 16/9    ]\n") {
+      cerr << s;
+      BOOST_ERROR("(zero-padded user-type) formatting result incorrect");
+    }
+
+
+    s = str( format("%1%, %20T_ (%|2$5|,%|3$5|)\n") % "98765" % 1326 % 88 ) ;
+    if( s != "98765, _____________ ( 1326,   88)\n" )
+            BOOST_ERROR("(tabulation) formatting result incorrect");
+    s = str( format("%s, %|20t|=") % 88 ) ;
+    if( s != "88,                 =" ) {
+      cout << s << endl;
+      BOOST_ERROR("(tabulation) formatting result incorrect");
+    }
+
+
+    s = str(format("%.2s %8c.\n") % "root" % "user" );
+    if(s  != "ro        u.\n") {
+      cerr << s;
+      BOOST_ERROR("(truncation) formatting result incorrect");
+    }
+
+   // width in format-string is overridden by setw manipulator :
+    s = str( format("%|1$4| %|1$|") % group(setfill('0'), setw(6), 1) );
+    if( s!= "000001 000001")
+      BOOST_ERROR("width in format VS in argument misbehaved");
+
+    s = str( format("%|=s|") % group(setfill('_'), setw(6), r) );
+    if( s!= "_16/9_") {
+      cerr << s << endl;
+      BOOST_ERROR("width in group context is not handled correctly");
+    }
+
+
+    // options that uses internal alignment : + 0 #
+    s = str( format("%+6d %0#6x %s\n")  % 342 % 33 % "ok" );
+    if( s !="  +342 0x0021 ok\n")
+      BOOST_ERROR("(flags +, 0, or #) formatting result incorrect");
+
+    // flags in the format string are not sticky
+    // and hex in argument overrrides type-char d (->decimal) :
+    s = str( format("%2$#4d %|1$4| %|2$#4| %|3$|")
+             % 101
+             % group(setfill('_'), hex, 2)
+             % 103 );
+    if(s != "_0x2  101 _0x2 103")
+      BOOST_ERROR("formatting error. (not-restoring state ?)");
+
+
+
+    // flag '0' is tricky .
+    // left-align cancels '0':
+    s = str( format("%2$0#12X %2$0#-12d %1$0#10d \n") % -20 % 10 );
+    if( s != "0X000000000A 10           -000000020 \n"){
+      cerr << s;
+      BOOST_ERROR("formatting error. (flag 0)");
+    }
+
+    // actually testing floating point output is implementation
+    // specific so we're just going to do minimal checking...
+    double dbl = 1234567.890123f;
+
+#if (__cplusplus >= 201103L) || (BOOST_VERSION_NUMBER_MAJOR(BOOST_COMP_MSVC) >= 12)
+    // msvc-12.0 and later have support for hexfloat but do not set __cplusplus to a C++11 value
+    BOOST_TEST(boost::starts_with((boost::format("%A") % dbl).str(), "0X"));
+    BOOST_TEST(boost::starts_with((boost::format("%a") % dbl).str(), "0x"));
+#endif
+
+    BOOST_TEST(boost::contains((boost::format("%E") % dbl).str(), "E"));
+    BOOST_TEST(boost::contains((boost::format("%e") % dbl).str(), "e"));
+    BOOST_TEST(boost::contains((boost::format("%F") % dbl).str(), "."));
+    BOOST_TEST(boost::contains((boost::format("%f") % dbl).str(), "."));
+    BOOST_TEST(!(boost::format("%G") % dbl).str().empty());
+    BOOST_TEST(!(boost::format("%g") % dbl).str().empty());
+
+    // testing argument type parsing - remember argument types are ignored
+    // because operator % presents the argument type.
+    unsigned int value = 456;
+    BOOST_TEST_EQ((boost::format("%hhu") % value).str(), "456");
+    BOOST_TEST_EQ((boost::format("%hu") % value).str(), "456");
+    BOOST_TEST_EQ((boost::format("%lu") % value).str(), "456");
+    BOOST_TEST_EQ((boost::format("%llu") % value).str(), "456");
+    BOOST_TEST_EQ((boost::format("%ju") % value).str(), "456");
+    BOOST_TEST_EQ((boost::format("%zu") % value).str(), "456");
+    BOOST_TEST(boost::starts_with((boost::format("%Lf") % value).str(), "456"));
+
+#if !defined(BOOST_NO_STD_LOCALE)
+    // boolalpha support
+    std::locale loc;
+    const std::numpunct<char>& punk(std::use_facet<std::numpunct<char> >(loc));
+
+    // Demonstrates how to modify the default string to something else
+    std::locale custom(std::locale(), new custom_tf);
+    boost::ignore_unused(locale::global(custom));
+    BOOST_TEST_EQ((boost::format("%b") % false).str(), "NEGATIVE");
+    BOOST_TEST_EQ((boost::format("%b") % true).str(), "POSITIVE");
+
+    // restore system default
+    locale::global(loc);
+    BOOST_TEST_EQ((boost::format("%b") % false).str(), punk.falsename());
+    BOOST_TEST_EQ((boost::format("%b") % true).str(), punk.truename());
+#endif
+
+    // Support for microsoft argument type specifiers: 'w' (same as 'l'), I, I32, I64
+    BOOST_TEST_EQ((boost::format("%wc") % '5').str(), "5");
+    BOOST_TEST_EQ((boost::format("%Id") % 123).str(), "123");
+    BOOST_TEST_EQ((boost::format("%I32d") % 456).str(), "456");
+    BOOST_TEST_EQ((boost::format("%I64d") % 789).str(), "789");
+
+    // issue-36 volatile (and const) keyword
+    volatile int vint = 1234567;
+    BOOST_TEST_EQ((boost::format("%1%") % vint).str(), "1234567");
+    volatile const int vcint = 7654321;
+    BOOST_TEST_EQ((boost::format("%1%") % vcint).str(), "7654321");
+
+    // skip width if '*'
+    BOOST_TEST_EQ((boost::format("%*d") % vint).str(), "1234567");
+
+    // internal ios flag
+    BOOST_TEST_EQ((boost::format("%_6d") % -77).str(), "-   77");
+
+    // combining some flags
+    BOOST_TEST_EQ((boost::format("%+05.5d"  ) %  77).str(), "+0077");
+    BOOST_TEST_EQ((boost::format("%+ 5.5d"  ) %  77).str(), "  +77");
+    BOOST_TEST_EQ((boost::format("%+_ 5.5d" ) %  77).str(), "+  77");
+    BOOST_TEST_EQ((boost::format("%+- 5.5d" ) %  77).str(), "+77  ");
+    BOOST_TEST_EQ((boost::format("%+05.5d"  ) % -77).str(), "-0077");
+    BOOST_TEST_EQ((boost::format("%+ 5.5d"  ) % -77).str(), "  -77");
+    BOOST_TEST_EQ((boost::format("%+_ 5.5d" ) % -77).str(), "-  77");
+    BOOST_TEST_EQ((boost::format("%+- 5.5d" ) % -77).str(), "-77  ");
+
+    // reuse state and reset format flags
+    std::string mystr("abcdefghijklmnop");
+    BOOST_TEST_EQ((boost::format("%2.2s %-4.4s % 8.8s")
+        % mystr % mystr % mystr).str(), "ab abcd  abcdefg");
+
+    // coverage, operator =
+    format fmt("%1%%2%%3%");
+    fmt = fmt;
+
+    return boost::report_errors();
+}
diff --git a/test/format_test3.cpp b/test/format_test3.cpp
new file mode 100644
index 0000000..fa8c17e
--- /dev/null
+++ b/test/format_test3.cpp
@@ -0,0 +1,130 @@
+// ------------------------------------------------------------------------------
+// format_test3.cpp :  complicated format strings  and / or advanced uses
+// ------------------------------------------------------------------------------
+
+//  Copyright Samuel Krempp 2003. 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)
+
+// see http://www.boost.org/libs/format for library home page
+
+// ------------------------------------------------------------------------------
+
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/format.hpp>
+#include <iostream>
+#include <iomanip>
+
+struct Rational {
+  int n,d;
+  Rational (int an, int ad) : n(an), d(ad) {}
+};
+
+std::ostream& operator<<( std::ostream& os, const Rational& r) {
+  os << r.n << "/" << r.d;
+  return os;
+}
+
+int main(int, char* [])
+{
+    using namespace std;
+    using boost::format;
+    using boost::io::group;
+    using boost::str;
+
+    string s, s2;
+    // special paddings
+    s = str( format("[%=6s] [%+6s] [%+6s] [% 6s] [%+6s]\n")
+                      % 123
+                      % group(internal, setfill('W'), 234)
+                      % group(internal, setfill('X'), -345)
+                      % group(setfill('Y'), 456)
+                      % group(setfill('Z'), -10 ) );
+
+    if(s != "[  123 ] [+WW234] [-XX345] [YY 456] [ZZZ-10]\n" ) {
+      cerr << s ;
+      BOOST_ERROR("formatting error. (with special paddings)");
+    }
+
+    s = str( format("[% 6.8s] [% 8.6s] [% 7.7s]\n")
+                      % group(internal, setfill('x'), Rational(12345,54321))
+                      % group(internal, setfill('x'), Rational(123,45))
+                      % group(internal, setfill('x'), Rational(123,321))
+             );
+    if(s != (s2="[ 12345/5] [ xx123/4] [ 123/32]\n" )) {
+        cerr << s << s2;
+      BOOST_ERROR("formatting error. (with special paddings)");
+    }
+
+    s = str( format("[% 6.8s] [% 6.8s] [% 6.8s] [% 6.8s] [%6.8s]\n")
+                      % 1234567897
+                      % group(setfill('x'), 12)
+                      % group(internal, setfill('x'), 12)
+                      % group(internal, setfill('x'), 1234567890)
+                      % group(internal, setfill('x'), 123456)
+             );
+    if(s != (s2="[ 1234567] [xxx 12] [ xxx12] [ 1234567] [123456]\n") ) {
+        cerr << s << s2;
+      BOOST_ERROR("formatting error. (with special paddings)");
+    }
+
+    s = str( format("[% 8.6s] [% 6.4s] [% 6.4s] [% 8.6s] [% 8.6s]\n")
+                      % 1234567897
+                      % group(setfill('x'), 12)
+                      % group(internal, setfill('x'), 12)
+                      % group(internal, setfill('x'), 1234567890)
+                      % group(internal, setfill('x'), 12345)
+             );
+    if(s != (s2="[   12345] [xxx 12] [ xxx12] [ xx12345] [ xx12345]\n") ) {
+        cerr << s << s2;
+      BOOST_ERROR("formatting error. (with special paddings)");
+    }
+
+    // nesting formats :
+    s = str( format("%2$014x [%1%] %|2$05|\n") % (format("%05s / %s") % -18 % 7)
+             %group(showbase, -100)
+             );
+    if( s != "0x0000ffffff9c [-0018 / 7] -0100\n" ){
+      cerr << s ;
+      BOOST_ERROR("nesting did not work");
+    }
+
+    // bind args, and various arguments counts :
+    {
+        boost::format bf("%1% %4% %1%");
+        bf.bind_arg(1, "one") % 2 % "three" ;
+        BOOST_TEST_EQ(bf.expected_args(), 4);
+        BOOST_TEST_EQ(bf.fed_args(), 2);
+        BOOST_TEST_EQ(bf.bound_args(), 1);
+        BOOST_TEST_EQ(bf.remaining_args(), 1);
+        BOOST_TEST_EQ(bf.cur_arg(), 4);
+        bf.clear_binds();
+        bf % "one" % 2 % "three" ;
+        BOOST_TEST_EQ(bf.expected_args(), 4);
+        BOOST_TEST_EQ(bf.fed_args(), 3);
+        BOOST_TEST_EQ(bf.bound_args(), 0);
+        BOOST_TEST_EQ(bf.remaining_args(), 1);
+        BOOST_TEST_EQ(bf.cur_arg(), 4);
+    }
+    // testcase for bug reported at
+    // http://lists.boost.org/boost-users/2006/05/19723.php
+    {
+        format f("%40t%1%");
+        int x = 0;
+        f.bind_arg(1, x);
+        f.clear();
+    }
+
+    // testcase for bug reported at
+    // http://lists.boost.org/boost-users/2005/11/15454.php
+    std::string l_param;
+    std::string l_str = (boost::format("here is an empty string: %1%") % l_param).str();
+    BOOST_TEST_EQ(std::string("here is an empty string: "), l_str);
+
+    // testcase for SourceForge bug #1506914
+    std::string arg; // empty string
+    s = str(format("%=8s") % arg);
+    BOOST_TEST_EQ(std::string("        "), s);
+
+    return boost::report_errors();
+}
diff --git a/test/format_test_enum.cpp b/test/format_test_enum.cpp
new file mode 100644
index 0000000..ac4a4e8
--- /dev/null
+++ b/test/format_test_enum.cpp
@@ -0,0 +1,43 @@
+// ------------------------------------------------------------------------------
+//  format_test_enum.cpp :  test format use with enums
+// ------------------------------------------------------------------------------
+
+//  Copyright Steven Watanabe 2009.
+//
+//  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)
+
+//  See http://www.boost.org/libs/format for library home page
+
+// ------------------------------------------------------------------------------
+
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/format.hpp>
+
+enum enum_plain { PLAIN };
+enum { ANONYMOUS };
+enum enum_overloaded { OVERLOADED };
+typedef enum { OVERLOADED_TYPEDEF } enum_overloaded_typedef;
+
+std::ostream& operator<<(std::ostream& os, enum_overloaded) {
+    os << "overloaded";
+    return(os);
+}
+
+std::ostream& operator<<(std::ostream& os, enum_overloaded_typedef) {
+    os << "overloaded";
+    return(os);
+}
+
+int main(int, char*[]) {
+    // in this case, we should implicitly convert to int
+    BOOST_TEST_EQ((boost::format("%d") % PLAIN).str(), "0");
+    BOOST_TEST_EQ((boost::format("%d") % ANONYMOUS).str(), "0");
+
+    // but here we need to use the overloaded operator
+    BOOST_TEST_EQ((boost::format("%s") % OVERLOADED).str(), "overloaded");
+    BOOST_TEST_EQ((boost::format("%s") % OVERLOADED_TYPEDEF).str(), "overloaded");
+
+    return boost::report_errors();
+}
diff --git a/test/format_test_exceptions.cpp b/test/format_test_exceptions.cpp
new file mode 100644
index 0000000..4ef579a
--- /dev/null
+++ b/test/format_test_exceptions.cpp
@@ -0,0 +1,105 @@
+// ------------------------------------------------------------------------------
+// format_test_exceptions.cpp : exception handling
+// ------------------------------------------------------------------------------
+
+//  Copyright 2017 James E. King, III - 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)
+
+// see http://www.boost.org/libs/format for library home page
+
+// ------------------------------------------------------------------------------
+
+#include <boost/algorithm/string.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/format.hpp>
+#include <iomanip>
+#include <iostream>
+
+#define CHECK_INVALID_0(FMT, EX) { BOOST_TEST_THROWS((boost::format(FMT)).str(), EX); \
+    boost::format safe; safe.exceptions(boost::io::no_error_bits); safe.parse(FMT); (safe).str(); }
+#define CHECK_INVALID_1(FMT, _1, EX) { BOOST_TEST_THROWS((boost::format(FMT) % _1).str(), EX); \
+    boost::format safe; safe.exceptions(boost::io::no_error_bits); safe.parse(FMT); (safe % _1).str(); }
+#define CHECK_INVALID_2(FMT, _1, _2, EX) { BOOST_TEST_THROWS((boost::format(FMT) % _1 % _2).str(), EX); \
+    boost::format safe; safe.exceptions(boost::io::no_error_bits); safe.parse(FMT); (safe % _1 % _2).str(); }
+
+int main(int, char* [])
+{
+    using namespace boost::io;
+
+    // https://svn.boost.org/trac10/ticket/8735
+
+    CHECK_INVALID_0("%", bad_format_string);          // no conversion specifier
+    CHECK_INVALID_0("%|", bad_format_string);         // truncated
+    CHECK_INVALID_0("%|%", bad_format_string);        // mismatched bars
+    CHECK_INVALID_0("%|2%", bad_format_string);       // mismatched bars
+    CHECK_INVALID_0("%'", bad_format_string);         // flag ' is ignored, no conversion specifier
+    CHECK_INVALID_0("%2", bad_format_string);         // no terminating percent
+    CHECK_INVALID_0("%*", bad_format_string);         // truncated
+    CHECK_INVALID_1("%$2", 1, bad_format_string);     // no conversion specifier
+    CHECK_INVALID_1("%$2.*", 1, bad_format_string);   // no conversion specifier
+    CHECK_INVALID_0("%0%", bad_format_string);        // positional arguments start at 1
+    CHECK_INVALID_2("%1%", 1, 2, too_many_args);
+    CHECK_INVALID_1("%1% %2%", 1, too_few_args);
+
+    CHECK_INVALID_0("%I", bad_format_string);
+    CHECK_INVALID_0("%I2", bad_format_string);
+    CHECK_INVALID_0("%I2d", bad_format_string);
+    CHECK_INVALID_0("%I3", bad_format_string);
+    CHECK_INVALID_0("%I3d", bad_format_string);
+    CHECK_INVALID_0("%I32", bad_format_string);
+    CHECK_INVALID_0("%I33", bad_format_string);
+    CHECK_INVALID_0("%I6", bad_format_string);
+    CHECK_INVALID_0("%I62", bad_format_string);
+    CHECK_INVALID_0("%I63", bad_format_string);
+    CHECK_INVALID_0("%I63d", bad_format_string);
+    CHECK_INVALID_0("%I64", bad_format_string);
+    CHECK_INVALID_0("%I128d", bad_format_string);
+    CHECK_INVALID_0("%3.*4d", bad_format_string);
+
+    // mixing positional and non-positional
+    CHECK_INVALID_2("%1% %2d", 1, 2, bad_format_string);
+    CHECK_INVALID_2("%2d %2%", 1, 2, bad_format_string);
+
+    // found while improving coverage - a number following the * for width
+    // or precision was being eaten instead of being treated as an error
+    CHECK_INVALID_0("%1$*4d", bad_format_string);
+    CHECK_INVALID_0("%1$05.*32d", bad_format_string);
+    CHECK_INVALID_0("%1$05.*6", bad_format_string);
+
+    // found while improving coverage, this caused an unhandled exception
+    // the "T" conversion specifier didn't handle the exception flags properly
+    CHECK_INVALID_0("%1$T", bad_format_string);       // missing fill character
+
+    // test what() on exceptions
+    format_error base_err;
+    BOOST_TEST_GT(strlen(base_err.what()), 0u);
+
+    bad_format_string bfs(2, 3);
+    BOOST_TEST(boost::contains(bfs.what(), "bad_format_string"));
+
+    too_few_args tfa(5, 4);
+    BOOST_TEST(boost::contains(tfa.what(), "format-string"));
+
+    too_many_args tma(4, 5);
+    BOOST_TEST(boost::contains(tma.what(), "format-string"));
+
+    boost::io::out_of_range oor(1, 2, 3);
+    BOOST_TEST(boost::contains(oor.what(), "out_of_range"));
+
+    // bind and unbind
+    boost::format two("%1%, %2%");
+    two.bind_arg(1, 1);
+    two.bind_arg(2, 2);
+    BOOST_TEST_EQ(two.str(), "1, 2");
+
+    two.clear_bind(1);
+    BOOST_TEST_THROWS(two.str(), too_few_args);
+    BOOST_TEST_THROWS(two.clear_bind(1), boost::io::out_of_range);
+    two.exceptions(no_error_bits);
+    two.clear_bind(1);
+    two.str();
+
+    return boost::report_errors();
+}
+
diff --git a/test/format_test_wstring.cpp b/test/format_test_wstring.cpp
new file mode 100644
index 0000000..2d22472
--- /dev/null
+++ b/test/format_test_wstring.cpp
@@ -0,0 +1,40 @@
+// ------------------------------------------------------------------------------
+//  format_test_wstring.cpp :  test wchar_t format use (if supported)
+// ------------------------------------------------------------------------------
+
+//  Copyright Samuel Krempp 2003. 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)
+
+//  See http://www.boost.org/libs/format for library home page
+
+// ------------------------------------------------------------------------------
+
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/format.hpp>
+
+int main(int, char* [])
+{
+  using boost::format;
+  using boost::str;
+
+#if !defined(BOOST_NO_STD_WSTRING) && !defined(BOOST_NO_STD_WSTREAMBUF)
+  using boost::wformat;
+  wformat wfmter(L"%%##%%##%%1 %1%00");
+  if(str( wfmter % L"Escaped OK" ) != L"%##%##%1 Escaped OK00")
+      BOOST_ERROR("Basic w-parsing Failed");
+  if(str( wformat(L"%%##%#x ##%%1 %s00") % 20 % L"Escaped OK" ) != L"%##0x14 ##%1 Escaped OK00")
+      BOOST_ERROR("Basic wp-parsing Failed") ;
+
+  // testcase for https://svn.boost.org/trac10/ticket/7379 (for valgrind)
+  wformat wfmt(L"%1$.1f");
+  std::wstring ws = str(wfmt % 123.45f);
+  BOOST_TEST_EQ(ws.compare(L"123.4"), 0);
+  wformat wfmt2(L"%1$.0f %%");
+  std::wstring ws2 = (wfmt2 % 123.45f).str();
+  BOOST_TEST_EQ(ws2.compare(L"123 %"), 0);
+
+#endif // wformat tests
+
+  return boost::report_errors();
+}
diff --git a/tools/Jamfile.v2 b/tools/Jamfile.v2
new file mode 100644
index 0000000..fe14823
--- /dev/null
+++ b/tools/Jamfile.v2
@@ -0,0 +1,18 @@
+#  Boost.Format Library tools Jamfile
+#
+#  Copyright (c) 2017 James E. King, III
+#
+#  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)
+
+project
+    : requirements
+	  <define>_CRT_SECURE_NO_WARNINGS
+	  <link>static
+	;
+
+exe format_matrix 
+    : format_matrix.cpp
+	  /boost/program_options//boost_program_options
+	  /boost/system//boost_system
+    ;
diff --git a/tools/format_matrix.cpp b/tools/format_matrix.cpp
new file mode 100644
index 0000000..eaacce1
--- /dev/null
+++ b/tools/format_matrix.cpp
@@ -0,0 +1,476 @@
+// ------------------------------------------------------------------------------
+//  format_matrix.cpp : tool to check for regressions between boost format
+//                      releases and compare format specification handling
+// ------------------------------------------------------------------------------
+
+//  Copyright 2017 James E. King, III. 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)
+
+//  See http://www.boost.org/libs/format for library home page
+
+// ------------------------------------------------------------------------------
+// reference (ISO C99)   : http://en.cppreference.com/w/cpp/io/c/fprintf
+// reference (Java)      : http://docs.oracle.com/javase/8/docs/api/java/util/Formatter.html
+// reference (Microsoft) : https://docs.microsoft.com/en-us/cpp/c-runtime-library/format-specification-syntax-printf-and-wprintf-functions
+// reference (POSIX 2008): http://pubs.opengroup.org/onlinepubs/9699919799/functions/printf.html
+
+#include <boost/array.hpp>
+#include <boost/config.hpp>
+#include <boost/cstdint.hpp>
+#include <boost/filesystem/path.hpp>
+#include <boost/format.hpp>
+#include <boost/io/ios_state.hpp>
+#include <boost/predef.h>
+#include <boost/program_options.hpp>
+#include <cerrno>
+#include <climits>
+#include <clocale>
+#if BOOST_COMP_MSVC && BOOST_VERSION_NUMBER_MAJOR(BOOST_COMP_MSVC) >= 19
+#include <corecrt.h>    // wint_t
+#endif
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <cwchar>
+#include <fstream>
+#include <iomanip>
+#include <iostream>
+#include <math.h>
+
+#define SNPRINTF snprintf
+#if BOOST_COMP_MSVC && BOOST_VERSION_NUMBER_MAJOR(BOOST_COMP_MSVC) < 19
+#undef SNPRINTF
+#define SNPRINTF _snprintf
+#endif
+
+namespace fs = boost::filesystem;
+namespace po = boost::program_options;
+using namespace std;
+
+namespace matrix
+{
+
+enum interop_datatype
+{
+    // special types:
+    ID_UNDEF,           // undefined behavior according to the spec, so combination is not tested
+    ID_NOTSUP,          // behavior is not supported and therefore not tested currently
+
+    // boolean type values:
+    ID_BOOLF,           // false
+    ID_BOOLT,           // true
+
+    // string type values:
+    ID_CHAR,            // single signed character
+    ID_UCHAR,           // single unsigned character
+    ID_WCHAR,           // single wide character
+    ID_STR,             // C style string
+    ID_WSTR,            // C style wide string
+
+    // integer type values:
+    ID_ZERO,            // zero value
+    ID_BYTE,            // int8_t
+    ID_UBYTE,           // uint8_t
+    ID_SHORT,           // signed short
+    ID_USHORT,          // unsigned short
+    ID_INT,             // signed integer
+    ID_UINT,            // unsigned integer
+    ID_LONG,            // signed long
+    ID_ULONG,           // unsigned long
+    ID_LLONG,           // signed long long
+    ID_ULLONG,          // unsigned long long
+    ID_INTMAX,          // intmax_t
+    ID_SSIZET,          // ssize_t
+    ID_SIZET,           // size_t
+    ID_SPTRDF,          // signed ptrdiff_t
+    ID_PTRDIF,          // ptrdiff_t
+
+    // floating type values:
+    ID_INF,             // infinity
+    ID_NAN,             // not a number
+    ID_DOUBLE,          // double
+    ID_NEGDBL,          // negative double
+    ID_LNGDBL,          // long double
+    ID_NEGLNG           // negative long double
+};
+
+BOOST_CONSTEXPR const bool            g_bf  = false;
+BOOST_CONSTEXPR const bool            g_bt  = true;
+BOOST_CONSTEXPR const uint64_t        g_z   = 0;
+BOOST_CONSTEXPR const char            g_by  = 0x60;
+BOOST_CONSTEXPR const unsigned char   g_uby = 0xA0;
+BOOST_CONSTEXPR const char            g_c   = 0x58;
+BOOST_CONSTEXPR const wint_t          g_wc  = L'X';          // 'X', but wide
+BOOST_CONSTEXPR const char *          g_s   = " string"; 
+BOOST_CONSTEXPR const wchar_t *       g_ws  = L"widestr";
+BOOST_CONSTEXPR const short           g_h   = numeric_limits<short>::min() + 12345;
+BOOST_CONSTEXPR const unsigned short  g_uh  = numeric_limits<unsigned short>::max() - 12345;
+BOOST_CONSTEXPR const int             g_i   = numeric_limits<int>::max() - 12345;
+BOOST_CONSTEXPR const unsigned int    g_ui  = numeric_limits<unsigned int>::max() - 12345;
+BOOST_CONSTEXPR const long            g_l   = numeric_limits<long>::max() - 12345;
+BOOST_CONSTEXPR const unsigned long   g_ul  = numeric_limits<unsigned long>::max() - 12345;
+BOOST_CONSTEXPR const int64_t         g_ll  = numeric_limits<int64_t>::max() - 12345;
+BOOST_CONSTEXPR const uint64_t        g_ull = numeric_limits<uint64_t>::max() - 12345;
+BOOST_CONSTEXPR const intmax_t        g_max = numeric_limits<intmax_t>::max() - 12345;
+BOOST_CONSTEXPR const size_t          g_sst = numeric_limits<size_t>::min() - 12345;
+BOOST_CONSTEXPR const size_t          g_st  = numeric_limits<size_t>::max() - 12345;
+BOOST_CONSTEXPR const ptrdiff_t       g_pt  = numeric_limits<ptrdiff_t>::max() - 12345;
+BOOST_CONSTEXPR const double          g_db  = 1234567.891234f;
+BOOST_CONSTEXPR const double          g_ndb = -1234567.891234f;
+BOOST_CONSTEXPR const long double     g_ldb = 6543211234567.891234l;
+BOOST_CONSTEXPR const long double     g_nld = -6543211234567.891234l;
+#if defined(INFINITY)
+BOOST_CONSTEXPR const double          g_inf = INFINITY;
+#endif
+#if defined(NAN)
+BOOST_CONSTEXPR const double          g_nan = NAN;
+#endif
+
+boost::array<const char *, 12> length_modifier = { { "hh", "h", "", "l", "ll", "j", "z", "L", "w", "I", "I32", "I64" } };
+boost::array<const char *, 6>  format_flags    = { { "", "-", "+", " ", "#", "0" } };
+boost::array<const char *, 6>  minimum_width   = { { "", "1", "2", "5", "10", "20" } };           // TODO: , "*" } };
+boost::array<const char *, 7>  precision       = { { "", ".", ".0", ".2", ".5", ".10", ".20" } }; // TODO: , ".*" } };
+
+struct interop_row
+{
+    char conversion_specifier;
+    interop_datatype datatype[12];
+};
+
+// Each row represents a conversion specifier which is indicated in the first column
+// The subsequent columns are argument type specifiers for that conversion specifier
+// The data in the cell is the value to pass into snprintf and format to see what comes out
+
+interop_row interop_matrix[] = {
+    //         |----------------------------------- ISO C99 ---------------------------------------|   |-------------- Microsoft --------------|
+    //  spc,   hh       , h        , (none)   , l        , ll       , j        , z        , L        , w        , I        , I32      , I64 
+      { 'c', { ID_UNDEF , ID_UNDEF , ID_CHAR  , ID_WCHAR , ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_WCHAR , ID_UNDEF , ID_UNDEF , ID_UNDEF } },
+      { 's', { ID_UNDEF , ID_UNDEF , ID_STR   , ID_WSTR  , ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_WSTR  , ID_UNDEF , ID_UNDEF , ID_UNDEF } },
+
+      { 'd', { ID_BYTE  , ID_SHORT , ID_INT   , ID_LONG  , ID_LLONG , ID_INTMAX, ID_SSIZET, ID_UNDEF , ID_UNDEF , ID_SPTRDF, ID_INT   , ID_LLONG } },
+      { 'd', { ID_UBYTE , ID_USHORT, ID_UINT  , ID_ULONG , ID_ULLONG, ID_INTMAX, ID_SIZET , ID_UNDEF , ID_UNDEF , ID_PTRDIF, ID_UINT  , ID_ULLONG} },
+      { 'd', { ID_ZERO  , ID_ZERO  , ID_ZERO  , ID_ZERO  , ID_ZERO  , ID_ZERO  , ID_ZERO  , ID_UNDEF , ID_UNDEF , ID_ZERO  , ID_ZERO  , ID_ZERO  } },
+      { 'i', { ID_BYTE  , ID_SHORT , ID_INT   , ID_LONG  , ID_LLONG , ID_INTMAX, ID_SSIZET, ID_UNDEF , ID_UNDEF , ID_SPTRDF, ID_INT   , ID_LLONG } },
+      { 'i', { ID_UBYTE , ID_USHORT, ID_UINT  , ID_ULONG , ID_ULLONG, ID_INTMAX, ID_SIZET , ID_UNDEF , ID_UNDEF , ID_PTRDIF, ID_UINT  , ID_ULLONG} },
+      { 'i', { ID_ZERO  , ID_ZERO  , ID_ZERO  , ID_ZERO  , ID_ZERO  , ID_ZERO  , ID_ZERO  , ID_UNDEF , ID_UNDEF , ID_ZERO  , ID_ZERO  , ID_ZERO  } },
+
+      { 'o', { ID_UBYTE , ID_USHORT, ID_UINT  , ID_ULONG , ID_ULLONG, ID_INTMAX, ID_SIZET , ID_UNDEF , ID_UNDEF , ID_PTRDIF, ID_UINT  , ID_ULLONG} },
+      { 'o', { ID_ZERO  , ID_ZERO  , ID_ZERO  , ID_ZERO  , ID_ZERO  , ID_ZERO  , ID_ZERO  , ID_UNDEF , ID_UNDEF , ID_ZERO  , ID_ZERO  , ID_ZERO  } },
+      { 'x', { ID_UBYTE , ID_USHORT, ID_UINT  , ID_ULONG , ID_ULLONG, ID_INTMAX, ID_SIZET , ID_UNDEF , ID_UNDEF , ID_PTRDIF, ID_UINT  , ID_ULLONG} },
+      { 'x', { ID_ZERO  , ID_ZERO  , ID_ZERO  , ID_ZERO  , ID_ZERO  , ID_ZERO  , ID_ZERO  , ID_UNDEF , ID_UNDEF , ID_ZERO  , ID_ZERO  , ID_ZERO  } },
+      { 'X', { ID_UBYTE , ID_USHORT, ID_UINT  , ID_ULONG , ID_ULLONG, ID_INTMAX, ID_SIZET , ID_UNDEF , ID_UNDEF , ID_PTRDIF, ID_UINT  , ID_ULLONG} },
+      { 'X', { ID_ZERO  , ID_ZERO  , ID_ZERO  , ID_ZERO  , ID_ZERO  , ID_ZERO  , ID_ZERO  , ID_UNDEF , ID_UNDEF , ID_ZERO  , ID_ZERO  , ID_ZERO  } },
+      { 'u', { ID_UBYTE , ID_USHORT, ID_UINT  , ID_ULONG , ID_ULLONG, ID_INTMAX, ID_SIZET , ID_UNDEF , ID_UNDEF , ID_PTRDIF, ID_UINT  , ID_ULLONG} },
+      { 'u', { ID_ZERO  , ID_ZERO  , ID_ZERO  , ID_ZERO  , ID_ZERO  , ID_ZERO  , ID_ZERO  , ID_UNDEF , ID_UNDEF , ID_ZERO  , ID_ZERO  , ID_ZERO  } },
+
+      { 'f', { ID_UNDEF , ID_UNDEF , ID_DOUBLE, ID_DOUBLE, ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_LNGDBL, ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_UNDEF } },
+      { 'f', { ID_UNDEF , ID_UNDEF , ID_NEGDBL, ID_NEGDBL, ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_NEGLNG, ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_UNDEF } },
+      { 'f', { ID_UNDEF , ID_UNDEF , ID_INF   , ID_INF   , ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_INF   , ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_UNDEF } },
+      { 'f', { ID_UNDEF , ID_UNDEF , ID_NAN   , ID_NAN   , ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_NAN   , ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_UNDEF } },
+      { 'f', { ID_UNDEF , ID_UNDEF , ID_ZERO  , ID_ZERO  , ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_ZERO  , ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_UNDEF } },
+      { 'F', { ID_UNDEF , ID_UNDEF , ID_DOUBLE, ID_DOUBLE, ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_LNGDBL, ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_UNDEF } },
+      { 'F', { ID_UNDEF , ID_UNDEF , ID_NEGDBL, ID_NEGDBL, ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_NEGLNG, ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_UNDEF } },
+      { 'F', { ID_UNDEF , ID_UNDEF , ID_INF   , ID_INF   , ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_INF   , ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_UNDEF } },
+      { 'F', { ID_UNDEF , ID_UNDEF , ID_NAN   , ID_NAN   , ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_NAN   , ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_UNDEF } },
+      { 'F', { ID_UNDEF , ID_UNDEF , ID_ZERO  , ID_ZERO  , ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_ZERO  , ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_UNDEF } },
+      { 'e', { ID_UNDEF , ID_UNDEF , ID_DOUBLE, ID_DOUBLE, ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_LNGDBL, ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_UNDEF } },
+      { 'e', { ID_UNDEF , ID_UNDEF , ID_NEGDBL, ID_NEGDBL, ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_NEGLNG, ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_UNDEF } },
+      { 'e', { ID_UNDEF , ID_UNDEF , ID_INF   , ID_INF   , ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_INF   , ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_UNDEF } },
+      { 'e', { ID_UNDEF , ID_UNDEF , ID_NAN   , ID_NAN   , ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_NAN   , ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_UNDEF } },
+      { 'e', { ID_UNDEF , ID_UNDEF , ID_ZERO  , ID_ZERO  , ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_ZERO  , ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_UNDEF } },
+      { 'E', { ID_UNDEF , ID_UNDEF , ID_DOUBLE, ID_DOUBLE, ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_LNGDBL, ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_UNDEF } },
+      { 'E', { ID_UNDEF , ID_UNDEF , ID_NEGDBL, ID_NEGDBL, ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_NEGLNG, ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_UNDEF } },
+      { 'E', { ID_UNDEF , ID_UNDEF , ID_INF   , ID_INF   , ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_INF   , ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_UNDEF } },
+      { 'E', { ID_UNDEF , ID_UNDEF , ID_NAN   , ID_NAN   , ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_NAN   , ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_UNDEF } },
+      { 'E', { ID_UNDEF , ID_UNDEF , ID_ZERO  , ID_ZERO  , ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_ZERO  , ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_UNDEF } },
+      { 'a', { ID_UNDEF , ID_UNDEF , ID_DOUBLE, ID_DOUBLE, ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_LNGDBL, ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_UNDEF } },
+      { 'a', { ID_UNDEF , ID_UNDEF , ID_NEGDBL, ID_NEGDBL, ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_NEGLNG, ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_UNDEF } },
+      { 'a', { ID_UNDEF , ID_UNDEF , ID_INF   , ID_INF   , ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_INF   , ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_UNDEF } },
+      { 'a', { ID_UNDEF , ID_UNDEF , ID_NAN   , ID_NAN   , ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_NAN   , ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_UNDEF } },
+      { 'a', { ID_UNDEF , ID_UNDEF , ID_ZERO  , ID_ZERO  , ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_ZERO  , ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_UNDEF } },
+      { 'A', { ID_UNDEF , ID_UNDEF , ID_DOUBLE, ID_DOUBLE, ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_LNGDBL, ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_UNDEF } },
+      { 'A', { ID_UNDEF , ID_UNDEF , ID_NEGDBL, ID_NEGDBL, ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_NEGLNG, ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_UNDEF } },
+      { 'A', { ID_UNDEF , ID_UNDEF , ID_INF   , ID_INF   , ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_INF   , ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_UNDEF } },
+      { 'A', { ID_UNDEF , ID_UNDEF , ID_NAN   , ID_NAN   , ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_NAN   , ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_UNDEF } },
+      { 'A', { ID_UNDEF , ID_UNDEF , ID_ZERO  , ID_ZERO  , ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_ZERO  , ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_UNDEF } },
+      { 'g', { ID_UNDEF , ID_UNDEF , ID_DOUBLE, ID_DOUBLE, ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_LNGDBL, ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_UNDEF } },
+      { 'g', { ID_UNDEF , ID_UNDEF , ID_NEGDBL, ID_NEGDBL, ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_NEGLNG, ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_UNDEF } },
+      { 'g', { ID_UNDEF , ID_UNDEF , ID_INF   , ID_INF   , ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_INF   , ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_UNDEF } },
+      { 'g', { ID_UNDEF , ID_UNDEF , ID_NAN   , ID_NAN   , ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_NAN   , ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_UNDEF } },
+      { 'g', { ID_UNDEF , ID_UNDEF , ID_ZERO  , ID_ZERO  , ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_ZERO  , ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_UNDEF } },
+      { 'G', { ID_UNDEF , ID_UNDEF , ID_DOUBLE, ID_DOUBLE, ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_LNGDBL, ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_UNDEF } },
+      { 'G', { ID_UNDEF , ID_UNDEF , ID_NEGDBL, ID_NEGDBL, ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_NEGLNG, ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_UNDEF } },
+      { 'G', { ID_UNDEF , ID_UNDEF , ID_INF   , ID_INF   , ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_INF   , ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_UNDEF } },
+      { 'G', { ID_UNDEF , ID_UNDEF , ID_NAN   , ID_NAN   , ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_NAN   , ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_UNDEF } },
+      { 'G', { ID_UNDEF , ID_UNDEF , ID_ZERO  , ID_ZERO  , ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_ZERO  , ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_UNDEF } },
+
+    // boolalpha - not supported in snprintf per ISO C99 but is by boost::format so...
+      { 'b', { ID_UNDEF , ID_UNDEF , ID_BOOLF , ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_UNDEF } },
+      { 'b', { ID_UNDEF , ID_UNDEF , ID_BOOLT , ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_UNDEF } },
+
+    // this is the terminator for conversion specifier loops:
+      {  0 , { ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_UNDEF , ID_UNDEF } },
+};
+
+std::string call_snprintf(const std::string& fmtStr, interop_datatype type)
+{
+    // enough space to hold any value in this test
+    char buf[BUFSIZ];
+    int len = 0;
+
+    switch (type)
+    {
+        case ID_ZERO:   len = SNPRINTF(buf, BUFSIZ, fmtStr.c_str(), g_z  ); break;
+        case ID_BOOLF:  len = SNPRINTF(buf, BUFSIZ, fmtStr.c_str(), g_bf ); break;
+        case ID_BOOLT:  len = SNPRINTF(buf, BUFSIZ, fmtStr.c_str(), g_bt ); break;
+        case ID_BYTE:   len = SNPRINTF(buf, BUFSIZ, fmtStr.c_str(), g_by ); break;
+        case ID_UBYTE:  len = SNPRINTF(buf, BUFSIZ, fmtStr.c_str(), g_uby); break;
+        case ID_CHAR:   len = SNPRINTF(buf, BUFSIZ, fmtStr.c_str(), g_c  ); break;
+        case ID_WCHAR:  len = SNPRINTF(buf, BUFSIZ, fmtStr.c_str(), g_wc ); break;
+        case ID_STR:    len = SNPRINTF(buf, BUFSIZ, fmtStr.c_str(), g_s  ); break;
+        case ID_WSTR:   len = SNPRINTF(buf, BUFSIZ, fmtStr.c_str(), g_ws ); break;
+        case ID_SHORT:  len = SNPRINTF(buf, BUFSIZ, fmtStr.c_str(), g_h  ); break;
+        case ID_USHORT: len = SNPRINTF(buf, BUFSIZ, fmtStr.c_str(), g_uh ); break;
+        case ID_INT:    len = SNPRINTF(buf, BUFSIZ, fmtStr.c_str(), g_i  ); break;
+        case ID_UINT:   len = SNPRINTF(buf, BUFSIZ, fmtStr.c_str(), g_ui ); break;
+        case ID_LONG:   len = SNPRINTF(buf, BUFSIZ, fmtStr.c_str(), g_l  ); break;
+        case ID_ULONG:  len = SNPRINTF(buf, BUFSIZ, fmtStr.c_str(), g_ul ); break;
+        case ID_LLONG:  len = SNPRINTF(buf, BUFSIZ, fmtStr.c_str(), g_ll ); break;
+        case ID_ULLONG: len = SNPRINTF(buf, BUFSIZ, fmtStr.c_str(), g_ull); break;
+        case ID_INTMAX: len = SNPRINTF(buf, BUFSIZ, fmtStr.c_str(), g_max); break;
+        case ID_SSIZET: len = SNPRINTF(buf, BUFSIZ, fmtStr.c_str(), g_sst); break;
+        case ID_SIZET:  len = SNPRINTF(buf, BUFSIZ, fmtStr.c_str(), g_st ); break;
+        case ID_SPTRDF: len = SNPRINTF(buf, BUFSIZ, fmtStr.c_str(), g_pt ); break;
+        case ID_PTRDIF: len = SNPRINTF(buf, BUFSIZ, fmtStr.c_str(), g_pt ); break;
+#if defined(INFINITY)
+        case ID_INF:    len = SNPRINTF(buf, BUFSIZ, fmtStr.c_str(), g_inf); break;
+#endif
+#if defined(NAN)
+        case ID_NAN:    len = SNPRINTF(buf, BUFSIZ, fmtStr.c_str(), g_nan); break;
+#endif
+        case ID_DOUBLE: len = SNPRINTF(buf, BUFSIZ, fmtStr.c_str(), g_db ); break;
+        case ID_NEGDBL: len = SNPRINTF(buf, BUFSIZ, fmtStr.c_str(), g_ndb); break;
+        case ID_LNGDBL: len = SNPRINTF(buf, BUFSIZ, fmtStr.c_str(), g_ldb); break;
+        case ID_NEGLNG: len = SNPRINTF(buf, BUFSIZ, fmtStr.c_str(), g_nld); break;
+        default: throw logic_error("unhandled type in call_snprintf");
+    }
+
+    if (len < 0)
+    {
+        throw logic_error("snprintf length 0");
+    }
+
+    return std::string(buf, len);
+}
+
+std::string call_format(const std::string& fmtStr, interop_datatype type)
+{
+    switch (type)
+    {
+        case ID_ZERO:   return ::boost::str(::boost::format(fmtStr) % g_z  );
+        case ID_BOOLF:  return ::boost::str(::boost::format(fmtStr) % g_bf );
+        case ID_BOOLT:  return ::boost::str(::boost::format(fmtStr) % g_bt );
+        case ID_BYTE:   return ::boost::str(::boost::format(fmtStr) % g_by );
+        case ID_UBYTE:  return ::boost::str(::boost::format(fmtStr) % g_uby);
+        case ID_CHAR:   return ::boost::str(::boost::format(fmtStr) % g_c  );
+        case ID_WCHAR:  return ::boost::str(::boost::format(fmtStr) % g_wc );
+        case ID_STR:    return ::boost::str(::boost::format(fmtStr) % g_s  );
+        case ID_WSTR:   return ::boost::str(::boost::format(fmtStr) % g_ws );
+        case ID_SHORT:  return ::boost::str(::boost::format(fmtStr) % g_h  );
+        case ID_USHORT: return ::boost::str(::boost::format(fmtStr) % g_uh );
+        case ID_INT:    return ::boost::str(::boost::format(fmtStr) % g_i  );
+        case ID_UINT:   return ::boost::str(::boost::format(fmtStr) % g_ui );
+        case ID_LONG:   return ::boost::str(::boost::format(fmtStr) % g_l  );
+        case ID_ULONG:  return ::boost::str(::boost::format(fmtStr) % g_ul );
+        case ID_LLONG:  return ::boost::str(::boost::format(fmtStr) % g_ll );
+        case ID_ULLONG: return ::boost::str(::boost::format(fmtStr) % g_ull);
+        case ID_INTMAX: return ::boost::str(::boost::format(fmtStr) % g_max);
+        case ID_SSIZET: return ::boost::str(::boost::format(fmtStr) % g_sst);
+        case ID_SIZET:  return ::boost::str(::boost::format(fmtStr) % g_st );
+        case ID_SPTRDF: return ::boost::str(::boost::format(fmtStr) % g_pt );
+        case ID_PTRDIF: return ::boost::str(::boost::format(fmtStr) % g_pt );
+#if defined(INFINITY)
+        case ID_INF:    return ::boost::str(::boost::format(fmtStr) % g_inf);
+#endif
+#if defined(NAN)
+        case ID_NAN:    return ::boost::str(::boost::format(fmtStr) % g_nan);
+#endif
+        case ID_DOUBLE: return ::boost::str(::boost::format(fmtStr) % g_db );
+        case ID_NEGDBL: return ::boost::str(::boost::format(fmtStr) % g_ndb);
+        case ID_LNGDBL: return ::boost::str(::boost::format(fmtStr) % g_ldb);
+        case ID_NEGLNG: return ::boost::str(::boost::format(fmtStr) % g_nld);
+        default: throw logic_error("unhandled type in call_format");
+    }
+}
+
+po::variables_map g_args;
+ofstream g_os;
+
+void
+write_header()
+{
+    if (g_args.count("snprintf"))
+    {
+#if BOOST_LIB_C_GNU
+        g_os << "# glibc.version = " << BOOST_VERSION_NUMBER_MAJOR(BOOST_LIB_C_GNU) << "."
+                                     << BOOST_VERSION_NUMBER_MINOR(BOOST_LIB_C_GNU) << "."
+                                     << BOOST_VERSION_NUMBER_PATCH(BOOST_LIB_C_GNU)
+                                     << endl;
+#elif BOOST_COMP_MSVC
+        g_os << "# msvc.version = "  << BOOST_VERSION_NUMBER_MAJOR(BOOST_COMP_MSVC) << "."
+                                     << BOOST_VERSION_NUMBER_MINOR(BOOST_COMP_MSVC) << "."
+                                     << BOOST_VERSION_NUMBER_PATCH(BOOST_COMP_MSVC)
+                                     << endl;
+#else
+        g_os << "# libc.version = unknown" << endl;
+#endif
+    }
+    else
+    {
+        g_os << "# boost.version = " << BOOST_VERSION / 100000 << "."      // major version
+                                     << BOOST_VERSION / 100 % 1000 << "."  // minor version
+                                     << BOOST_VERSION % 100                // patch level
+                                     << endl;
+    }
+}
+
+void
+log(const std::string& spec, bool ok, const std::string& result)
+{
+    boost::io::ios_all_saver saver(g_os);
+    g_os << setw(20) << right << spec << "\t"
+         << (ok ? "OK " : "ERR") << "\t" << "\"" << result << "\"" << endl;
+}
+
+void cell(std::size_t nrow, std::size_t ncol)
+{
+    const interop_row& row(interop_matrix[nrow]);
+
+    const interop_datatype& dataType(row.datatype[ncol]);
+    if (dataType == ID_UNDEF || dataType == ID_NOTSUP)
+    {
+        return;
+    }
+
+#if !defined(INFINITY)
+    if (dataType == ID_INF)
+    {
+        return;
+    }
+#endif
+
+#if !defined(NAN)
+    if (dataType == ID_NAN)
+    {
+        return;
+    }
+#endif
+
+    // TODO: every combination of format flags - right now we do only one
+    for (std::size_t ffi = 0; ffi < format_flags.size(); ++ffi)
+    {
+        for (std::size_t mwi = 0; mwi < minimum_width.size(); ++mwi)
+        {
+            for (std::size_t pri = 0; pri < precision.size(); ++pri)
+            {
+                // Make the format string
+                std::stringstream fss;
+                fss << '%';
+                fss << format_flags[ffi];
+                fss << minimum_width[mwi];
+                fss << precision[pri];
+                fss << length_modifier[ncol];
+                fss << row.conversion_specifier;
+                std::string fmtStr = fss.str();
+
+                try
+                {
+                    std::string result = g_args.count("snprintf") ?
+                                            call_snprintf(fmtStr, dataType) : 
+                                            call_format  (fmtStr, dataType) ;
+                    log(fmtStr, true, result);
+                }
+                catch (const std::exception& ex)
+                {
+                    log(fmtStr, false, ex.what());
+                }
+            }
+        }
+    }
+}
+
+void
+matrix()
+{
+    for (std::size_t row = 0; interop_matrix[row].conversion_specifier != 0x00; ++row)
+    {
+        for (std::size_t col = 0; col < length_modifier.size(); ++col)
+        {
+            cell(row, col);
+        }
+    }
+}
+
+void
+write_pctpct()
+{
+    if (g_args.count("snprintf"))
+    {
+        char buf[BUFSIZ];
+        int len = SNPRINTF(buf, BUFSIZ, "%%");
+        log("%%", len == 1, len == 1 ? buf : "snprintf length != 1");
+    }
+    else
+    {
+        try
+        {
+            log("%%", true, ::boost::format("%%").str());
+        }
+        catch (std::exception& ex)
+        {
+            log("%%", false, ex.what());
+        }
+    }
+}
+
+void
+generate()
+{
+    string genpath = g_args["generate"].as<string>();
+    g_os.open(genpath.c_str(), ios::out | ios::trunc);
+    write_header();
+    write_pctpct();
+    matrix();
+    g_os.close();
+}
+
+} // matrix
+
+///////////////////////////////////////////////////////////////////////////////
+//  main entry point
+int
+main(int argc, char *argv[])
+{
+    using matrix::g_args;
+
+    po::options_description desc("Allowed options");
+    desc.add_options()
+        ("generate,g", po::value<string>()->required(), "generate output filename")
+        ("help,h", "produce help message")
+        ("snprintf,s", "use snprintf instead of boost::format")
+        ;
+
+    po::store(po::command_line_parser(argc, argv).options(desc).run(), g_args);
+    po::notify(g_args);
+
+    if (g_args.count("help")) {
+        cout << "Usage: format_matrix [options]\n";
+        cout << desc;
+        return 0;
+    }
+
+    matrix::generate();
+
+    return 0;
+}