boostorg / format Goto Github PK
View Code? Open in Web Editor NEWBoost.org format module
Home Page: http://boost.org/libs/format
License: Boost Software License 1.0
Boost.org format module
Home Page: http://boost.org/libs/format
License: Boost Software License 1.0
format/include/boost/format/alt_sstream_impl.hpp
Lines 40 to 45 in 7f4131b
Should use allocator_traits
when at least C++11 is detected instead; the above code produces a deprecation warning in some compiler configurations.
There might be some other code that should be updated as well, but this was the only one that I noticed a warning being flagged on (when compiling with VS2017 in C++17 mode).
In file included from src/config/printer.cpp:19:
In file included from ./include/bitcoin/system/config/printer.hpp:25:
In file included from /home/runner/work/libbitcoin-system/libbitcoin-system/prefixenv/include/boost/format.hpp:48:
/home/runner/work/libbitcoin-system/libbitcoin-system/prefixenv/include/boost/format/group.hpp:59:12: warning: definition of implicit copy constructor for 'group1<boost::io::detail::group0>' is deprecated because it has a user-declared copy assignment operator [-Wdeprecated-copy]
group1& operator=(const group1&);
^
/home/runner/work/libbitcoin-system/libbitcoin-system/prefixenv/include/boost/format/group.hpp:472:18: note: in implicit copy constructor for 'boost::io::detail::group1<boost::io::detail::group0>' first required here
group() { return detail::group1< detail::group0 > ( detail::group0() ); }
^
CXX src/config/libbitcoin_system_la-script.lo
1 warning generated.
https://github.com/evoskuil/libbitcoin-system/runs/6664512291?check_suite_focus=true#step:6:2861
Origin: https://www.boost.org/doc/libs/1_79_0/boost/format/group.hpp
This warning repeats heavily in all of versions of boost, and there are no other warnings in our clang builds, which incorporate many boost libraries. There is no apparent workaround apart from global warning suppression.
I know the docs say
the ' printf option (format with thousands grouping characters)) has no effect in format.
and the code says
format/include/boost/format/parsing.hpp
Lines 172 to 173 in c1170a6
but it would be really neat if this could be supported in the future.
I assume the issue is that Boost::format is essentially trying to achieve all (or at least the majority) of its formatting using standard stream flags and there is none for thousands separators?
From https://stackoverflow.com/questions/17530408/print-integer-with-thousands-and-millions-separator it seems that what would be necessary is to use a imbue in combination with a locale.
Has this been considered yet?
EDIT: This approach seems to at least break when using Boost::multiprecision numbers with the stream at which case the thousands separator is ignored again.
Line 127 is -
else if(way == ::std::ios_base::beg)
It is followed on line 129 -
else if(way != ::std::ios_base::beg)
Which, of course is always true given the previous test. This "impossible-redundant-condition" was spotted by a source analyser I used.
Newer versions of clang / gcc support a suggest-override warning: If you have a file format_error.cpp
#include <boost/format.hpp>
the compilation with e.g. Apple clang version 13.0.0 (clang-1300.0.29.3)
clang++ -std=c++11 -c -Werror=suggest-override format_error.cpp
will produce
In file included from format_error.cpp:1:
In file included from /usr/local/include/boost/format.hpp:44:
/usr/local/include/boost/format/exceptions.hpp:33:33: error: 'what' overrides a member function but is not marked 'override' [-Werror,-Wsuggest-override]
virtual const char *what() const throw() {
^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/c++/v1/exception:104:25: note: overridden virtual function is here
virtual const char* what() const _NOEXCEPT;
^
boost::format has a number of dependencies, some of which have moved to only supporting C++11:
Therefore boost::format must join them in only supporting C++11 or later.
We can reduce the complexity of CI builds a bit, dropping older compilers and the 98 and 03 language level builds.
In this page the output is broken because the source code file uses ISO-8859-1 but is assumed to be UTF-8 when copying to the web page. Github guesses the correct encoding so it displays properly
The server must be fixed to read the file in the correct encoding, or just convert all files to UTF-8. I think the latter is the best solution
This is a request from Dan Konigsbach on Boost Trac which I am moving to github issues.
Microsoft's printf implementation includes non-ANSI extensions to the valid length modifier prefixes: I, I32, and I64. boost::format currently does not recognize them.
It would ease migration to boost::format if parse_printf_directive() in format/parsing.hpp would parse and ignore them, just as it currently does with h and l.
(Note: I'd be willing to code the proposed enhancement, if that's appropriate.)
Thanks!!!! Dan K.
Reference: https://msdn.microsoft.com/en-us/library/56e442dc.aspx
Note that even though we could add parsing for these options, they would be summarily ignored by the current implementation because no conversion is done based on argument size. These modifiers are parsed and ignored because the type passed in defines the argument size.
If I try to format a (u)int8 number, Boost.Format considers this as (unsigned) char, even if I use %d
, %i
or %u
.
This is a known and rather old issue.
The workaround is to cast the number to (u)int32, before formatting.
Nevertheless the current behavior leads to very subtle bugs, because the developer has to check the type of the number to be printed very carefully.
Plain printf
handles (u)int8 numbers in combination with %d
, %i
or %u
correctly.
Boost version: 1.68 (32bit)
Compiler: MSVC 15.8
(none)
Tracking down a locale related bug in my source code, I found that the = operator of basic_format doesn't swap its locale, though the copy constructor does copy it. I find it confusing and hard to use this way, if i want to use a basic_format as a member and change it according to different needs.
format/include/boost/format/format_implementation.hpp
Lines 67 to 95 in 894f465
Add and map to std::hexfloat
behavior.
This is missing and should be added.
C Reference: http://en.cppreference.com/w/c/io/fprintf
C++11 Reference: http://en.cppreference.com/w/cpp/io/manip/fixed
We are in the process of making B2 build changes to all of the B2 build files
to support "modular" consumption of the Boost Libraries by users. See this list
post for some details: https://lists.boost.org/Archives/boost/2024/01/255704.php
The process requires making a variety of changes to make each Boost library
independent of the super-project structure. But the changes do not remove the
super-project structure or the comprehensive Boost release. The changes make
solely make it possible, optionally, for users, like package manages, to easily
consume libraries individually.
Generally the changes include:
Some examples of such changes:
We are asking how you would like us to handle the changes. We would prefer if
you allow the owners of the Boost.org GitHub project to make changes to B2
build files, as needed, to accomplish the changes. But understand
that you may want to manage the proposed changes yourself.
We previously sent emails to all known maintainers to fill out a form with their
preference. We are contacting you in this issue as we have not gotten a response
to that email. You can see the ongoing responses for that form and the responses
to these issues here https://github.com/users/grafikrobot/projects/1/views/6
We are now asking if you can reply directly to this issue to indicate your
preference of handling the changes. Please supply a response to this question
and close the issue (so that we can verify you are a maintainer).
How would you like the build changes to be processed?
Also please indicate any special instructions you want us to consider. Or other
information you want us to be aware of.
Thanks you, René
Per the Boost.Format documentation, argument types are ignored, however there are some newer ones that appeared in ISO C99 which should be parsed at least so that an exception is not thrown:
Currently, using 'hh'
, 'h'
, 'l'
, 'll'
, and 'L'
parse properly, however using 'j'
or 'z'
, cause a boost::io::bad_format_string
.
The argument type specifier 't'
from C++11 cannot be honored by boost::format because 'T'
and 't'
are used in boost::format for tabulations.
Originally reported by Paul Rose in Boost Trac.
struct A{
A() : a(9) {} int a;
}; A a; A volatile *pva = &a;
std::cout << boost::format("%d") % pva->a << std::endl;
This worked in 1_54 but fails in 1_56 with error:
format/feed_args.hpp:135:47: error: invalid conversion from 'volatile void*' to 'const void*'
Can work around this with cast:
std::cout << boost::format("%d") % (int)pva->a << std::endl;
but should not have to. The appearance to the user is pass by value.
Running linux with g++ 4.6.2 and 4.8.2
Originally reported in Boost 1.56.0.
Confirmed in Boost 1.59.0 with clang-3.8 on linux.
Confirmed in Boost 1.61.0 with VS2008.
Confirmed in Boost 1.63.0 with gcc-5.2.
format.hpp
refers to a macro BOOST_NO_LOCALE_ISIDIGIT
, which probably should be BOOST_NO_LOCALE_ISDIGIT
#include<string>
#include<iostream>
#include<iomanip>
#include<boost/format.hpp>
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 w = os.width(0); // width has to be zeroed before saving state.
boost::io::basic_oaltstringstream<char> oss;
oss.copyfmt(os);
oss << r.n_ << "/" << noshowpos << r.d_;
os.write(oss.begin(), oss.size());
return os;
}
int main(int argc, char* argv[])
{
using namespace std;
using boost::format;
using boost::io::group;
using boost::io::str;
std::printf("[%8s][%8s]\n", "format", "printf");
std::printf("\nright:\n");//'+'/' ', right
std::cerr << boost::format("[%+8d]") % 12; std::printf("[%+8d]\n", 12);
std::cerr << boost::format("[% 8d]") % 12; std::printf("[% 8d]\n", 12);
std::cerr << boost::format("[%+08d]") % 12; std::printf("[%+08d]\n", 12);
std::cerr << boost::format("[% 08d]") % 12; std::printf("[% 08d] !!!\n", 12);
std::printf("\ninternal:\n");//'+'/' ', internal('_')
std::cerr << boost::format("[%_+8d]\n") % 12;
std::cerr << boost::format("[%_ 8d]\n") % 12;
std::cerr << boost::format("[%_+08d]\n") % 12;
std::cerr << boost::format("[%_ 08d] !!!\n") % 12;
std::printf("\ncenter:\n");//'+'/' ', center('=')
std::cerr << boost::format("[%=+8d]\n") % 12;
std::cerr << boost::format("[%= 8d]\n") % 12;
std::cerr << boost::format("[%=+08d]\n") % 12;
std::cerr << boost::format("[%= 08d] !!!\n") % 12;
std::printf("\nleft:\n");//'+'/' ', left('-')
std::cerr << boost::format("[%-+8d]") % 12; std::printf("[%-+8d]\n", 12);
std::cerr << boost::format("[%- 8d]") % 12; std::printf("[%- 8d]\n", 12);
std::cerr << boost::format("[%-+08d]") % 12; std::printf("[%-+08d]\n", 12);
std::cerr << boost::format("[%- 08d]") % 12; std::printf("[%- 08d]\n", 12);
Rational r(16, 9);
std::printf("\nright:\n");
cerr << format("[%+8d]\n") % r;
cerr << format("[% 8d]\n") % r;
cerr << format("[%+08d]\n") % r;
cerr << format("[% 08d] !!!\n") % r;
std::printf("\ninternal:\n");
cerr << format("[%_+8d]\n") % r;
cerr << format("[%_ 8d]\n") % r;
cerr << format("[%_+08d]\n") % r;
cerr << format("[%_ 08d] !!!\n") % r;
std::printf("\ncenter:\n");
cerr << format("[%=+8d]\n") % r;
cerr << format("[%= 8d]\n") % r;
cerr << format("[%=+08d]\n") % r;
cerr << format("[%= 08d] !!!\n") % r;
std::printf("\nleft:\n");
cerr << format("[%-+8d]\n") % r;
cerr << format("[%- 8d]\n") % r;
cerr << format("[%-+08d]\n") % r;
cerr << format("[%- 08d]\n") % r;
}
output (boost.format on the left, std::printf on the right, the differences is marked with !!!
):
[ format][ printf]
right:
[ +12][ +12]
[ 12][ 12]
[+0000012][+0000012]
[00000012][ 0000012] !!!
internal:
[+ 12]
[ 12]
[+0000012]
[00000012] !!!
center:
[ +12 ]
[ 12 ]
[+0000012]
[00000012] !!!
left:
[+12 ][+12 ]
[ 12 ][ 12 ]
[+12 ][+12 ]
[ 12 ][ 12 ]
right:
[ +16/9]
[ 16/9]
[000+16/9]
[000016/9] !!!
internal:
[ +16/9]
[ 16/9]
[000+16/9]
[000016/9] !!!
center:
[ +16/9 ]
[ 16/9 ]
[000+16/9]
[000016/9] !!!
left:
[+16/9 ]
[ 16/9 ]
[+16/9 ]
[ 16/9 ]
I am working on identifying where boost::format and sprintf differ in behavior. I wrote a matrix test comparing standard sprintf to boost::format for purposes of ensuring that boost::format handles all of the format strings that sprintf does, and we're currently at about 41% pass rate. This matrix doesn't test every possible combination of format modifiers yet - just one of each was enough. Results are very early, and I will be working on improving this.
Here's some sample output from the test:
Format String | RSLT | "printf" | "boost::format" | error info
---------------------+------+---------------------------------------+---------------------------------------+--------------------------------------------------
% 1.5c | FAIL | "X" | " " | mismatch
% 1.20c | FAIL | "X" | " " | mismatch
% 2c | FAIL | " X" | " " | mismatch
% 2.c | FAIL | " X" | " " | mismatch
...
%5u | | "4294954950" | "4294954950" |
%5.u | | "4294954950" | "4294954950" |
%5.2u | | "4294954950" | "4294954950" |
%5.5u | | "4294954950" | "4294954950" |
%5.20u | FAIL | "00000000004294954950" | "4294954950" | mismatch
...
%020Lf | | "6543211234567.891602" | "6543211234567.891602" |
%020.Lf | | "00000006543211234568" | "00000006543211234568" |
%020.2Lf | | "00006543211234567.89" | "00006543211234567.89" |
%020.5Lf | | "06543211234567.89160" | "06543211234567.89160" |
%020.20Lf | | "6543211234567.89160156250000000000" | "6543211234567.89160156250000000000" |
%F | EXCP | "1234567.875000" | "" | boost::bad_format_string: format-string is ill-formed
...
%020LG | | "0000000006.54321E+12" | "0000000006.54321E+12" |
%020.LG | FAIL | "0000000000000007E+12" | "0000000006.54321E+12" | mismatch
%020.2LG | | "00000000000006.5E+12" | "00000000000006.5E+12" |
%020.5LG | | "00000000006.5432E+12" | "00000000006.5432E+12" |
%020.20LG | | "6543211234567.8916016" | "6543211234567.8916016" |
Failed Tests: 6707
Total Tests: 11401
Pass Rate: 41.2%
Per the original idea found in Francis (Grizzly) Smit's Boost Trac issue, add support for conversion specifier 'b'
that shall map to std::boolalpha
. Given that std::uppercase
only applies to numeric inputs, there will be no 'B'
conversion specifier support; instead one can follow this documentation to customize the boolean string output:
http://en.cppreference.com/w/cpp/locale/numpunct/truefalsename
It would be good if std::optional were used in projects that use C++2017.
A define like that which is available in boost.dll 1.70 would suffice in my opinion.
In general, Boost.Format is a stable and long-lived component and used by many consumers. Changes to the behavior of Boost.Format could cause widespread issues. A mechanism is needed that will allow comparison of one edition of Boost.Format to another to ensure there haven't been any regressions.
Create a matrix tester that will attempt to generate every possible format syntax string expression, and test against a variety of inputs appropriate to that type, and output the results to a text file which will be considered the results file. The results file format is:
# glibc.version = n
{format specification}<tab>OK |ERR<tab>string result or exception message
...
The tool will also allow for results to be generated against the platform's snprintf call, so that boost::format and snprintf on the same inputs and format specifications can be compared.
Hello. I have a problem with using std::variant with boost::format.
Visual Studio 2019 - 16.7.3
boost - 1.74
Sample code:
`
#include < iostream>
#include < variant>
#include <boost/variant.hpp>
#include <boost/format.hpp>
typedef std::variant<uint16_t, std::string> MemCaptureIdType;
//typedef boost::variant<uint16_t, std::string> MemCaptureIdType;
std::ostream& operator<<(std::ostream& os, const MemCaptureIdType& type)
{
return os;
}
int main()
{
auto tmp1 = MemCaptureIdType(0);
auto tmp = boost::format("%1%") % tmp1;
return 0;
}
`
But it works when I use boost::variant.
I think we need to support std::variant.
Boost test ‘test_json_parser’ in libs\property_tree\test failed with error C2589 C2760 when build with /permissive- in windows, this is source issue looks involved by bc53dbb#diff-67bfd7972eb56b5161d31780dbaa62a2
The source includes windows.h which defines the macro 'min' and 'max'. It need define ‘NOMINMAX’ before include ‘windows.h‘.
Environment: windows server 2016 + Visual studio 2017 update2 + Boost( master branch with latest revision ‘b30e350’)
Failures like:
test_json_parser.cpp
Info: Boost.Config is older than your compiler version - probably nothing bad will happen - but you may wish to look for an update Boost version. Define BOOST_CONFIG_SUPPRESS_OUTDATED_MESSAGE to suppress this message.
.\boost/format/feed_args.hpp(205): warning C4003: not enough actual parameters for macro 'max'
.\boost/format/feed_args.hpp(250): warning C4003: not enough actual parameters for macro 'max'
.\boost/format/feed_args.hpp(205): error C2589: '(': illegal token on right side of '::'
.\boost/format/feed_args.hpp(205): error C2760: syntax error: unexpected token '(', expected ')'
i.e. %07d will result in padding to 7 digits with zeros and %+d will show unpadded digits with plus sign if positive, but %+07d only shows the plus sign (if positive) but does not zero pad
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.