diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 18:45:59 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 18:45:59 +0000 |
commit | 19fcec84d8d7d21e796c7624e521b60d28ee21ed (patch) | |
tree | 42d26aa27d1e3f7c0b8bd3fd14e7d7082f5008dc /src/boost/libs/format | |
parent | Initial commit. (diff) | |
download | ceph-upstream.tar.xz ceph-upstream.zip |
Adding upstream version 16.2.11+ds.upstream/16.2.11+dsupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
22 files changed, 2522 insertions, 0 deletions
diff --git a/src/boost/libs/format/Jamfile b/src/boost/libs/format/Jamfile new file mode 100644 index 000000000..5f53e9bf2 --- /dev/null +++ b/src/boost/libs/format/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/src/boost/libs/format/LICENSE b/src/boost/libs/format/LICENSE new file mode 100644 index 000000000..36b7cd93c --- /dev/null +++ b/src/boost/libs/format/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/src/boost/libs/format/README.md b/src/boost/libs/format/README.md new file mode 100644 index 000000000..25c0b150f --- /dev/null +++ b/src/boost/libs/format/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/src/boost/libs/format/benchmark/Jamfile b/src/boost/libs/format/benchmark/Jamfile new file mode 100644 index 000000000..0a420ab32 --- /dev/null +++ b/src/boost/libs/format/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/src/boost/libs/format/benchmark/bench_format.cpp b/src/boost/libs/format/benchmark/bench_format.cpp new file mode 100644 index 000000000..393df7583 --- /dev/null +++ b/src/boost/libs/format/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/src/boost/libs/format/benchmark/results.txt b/src/boost/libs/format/benchmark/results.txt new file mode 100644 index 000000000..4a884defb --- /dev/null +++ b/src/boost/libs/format/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/src/boost/libs/format/example/Jamfile.v2 b/src/boost/libs/format/example/Jamfile.v2 new file mode 100644 index 000000000..6029e8976 --- /dev/null +++ b/src/boost/libs/format/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/src/boost/libs/format/example/sample_advanced.cpp b/src/boost/libs/format/example/sample_advanced.cpp new file mode 100644 index 000000000..049bf6ddd --- /dev/null +++ b/src/boost/libs/format/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/src/boost/libs/format/example/sample_formats.cpp b/src/boost/libs/format/example/sample_formats.cpp new file mode 100644 index 000000000..b1b6df93b --- /dev/null +++ b/src/boost/libs/format/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/src/boost/libs/format/example/sample_new_features.cpp b/src/boost/libs/format/example/sample_new_features.cpp new file mode 100644 index 000000000..53fffefec --- /dev/null +++ b/src/boost/libs/format/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/src/boost/libs/format/example/sample_userType.cpp b/src/boost/libs/format/example/sample_userType.cpp new file mode 100644 index 000000000..f35b926b4 --- /dev/null +++ b/src/boost/libs/format/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/src/boost/libs/format/index.html b/src/boost/libs/format/index.html new file mode 100644 index 000000000..52cd354d1 --- /dev/null +++ b/src/boost/libs/format/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 © 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/src/boost/libs/format/meta/libraries.json b/src/boost/libs/format/meta/libraries.json new file mode 100644 index 000000000..22fe8c2e0 --- /dev/null +++ b/src/boost/libs/format/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/src/boost/libs/format/test/Jamfile.v2 b/src/boost/libs/format/test/Jamfile.v2 new file mode 100644 index 000000000..f77f97c85 --- /dev/null +++ b/src/boost/libs/format/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/src/boost/libs/format/test/format_test1.cpp b/src/boost/libs/format/test/format_test1.cpp new file mode 100644 index 000000000..d259d2332 --- /dev/null +++ b/src/boost/libs/format/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/src/boost/libs/format/test/format_test2.cpp b/src/boost/libs/format/test/format_test2.cpp new file mode 100644 index 000000000..9fb061011 --- /dev/null +++ b/src/boost/libs/format/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/src/boost/libs/format/test/format_test3.cpp b/src/boost/libs/format/test/format_test3.cpp new file mode 100644 index 000000000..fa8c17e21 --- /dev/null +++ b/src/boost/libs/format/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/src/boost/libs/format/test/format_test_enum.cpp b/src/boost/libs/format/test/format_test_enum.cpp new file mode 100644 index 000000000..ac4a4e8ed --- /dev/null +++ b/src/boost/libs/format/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/src/boost/libs/format/test/format_test_exceptions.cpp b/src/boost/libs/format/test/format_test_exceptions.cpp new file mode 100644 index 000000000..4ef579ab6 --- /dev/null +++ b/src/boost/libs/format/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/src/boost/libs/format/test/format_test_wstring.cpp b/src/boost/libs/format/test/format_test_wstring.cpp new file mode 100644 index 000000000..2d224724f --- /dev/null +++ b/src/boost/libs/format/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/src/boost/libs/format/tools/Jamfile.v2 b/src/boost/libs/format/tools/Jamfile.v2 new file mode 100644 index 000000000..fe1482315 --- /dev/null +++ b/src/boost/libs/format/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/src/boost/libs/format/tools/format_matrix.cpp b/src/boost/libs/format/tools/format_matrix.cpp new file mode 100644 index 000000000..07bb7b92d --- /dev/null +++ b/src/boost/libs/format/tools/format_matrix.cpp @@ -0,0 +1,470 @@ +// ------------------------------------------------------------------------------ +// format_matrix.cpp : tool to check for regressions between boost format +// releases and compare format specification handling +// ------------------------------------------------------------------------------ + +// Copyright 2017 - 2019 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; + +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(), INFINITY); break; +#endif +#if defined(NAN) + case ID_NAN: len = SNPRINTF(buf, BUFSIZ, fmtStr.c_str(), 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) % INFINITY); +#endif +#if defined(NAN) + case ID_NAN: return ::boost::str(::boost::format(fmtStr) % 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; +} |