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/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;
+}