2019-10-16 17:04:41 +02:00
// The MIT License (MIT)
//
// Copyright (c) 2018 Mateusz Pusz
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// 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 AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
2021-03-30 13:21:05 +02:00
#include <units/customization_points.h>
2020-12-28 15:18:02 +01:00
#include <units/format.h>
2021-03-30 13:21:05 +02:00
#include <units/generic/dimensionless.h>
2021-03-16 12:03:25 +01:00
#include <units/isq/si/cgs/cgs.h>
2021-03-30 13:21:05 +02:00
#include <units/isq/si/si.h>
#include <units/math.h> // IWYU pragma: keep
2020-12-28 15:18:02 +01:00
#include <units/quantity_io.h>
2019-10-16 17:04:41 +02:00
#include <catch2/catch.hpp>
2020-03-19 09:23:27 +01:00
#include <iomanip>
2021-03-30 13:21:05 +02:00
#include <limits>
#include <locale>
2019-10-16 17:04:41 +02:00
using namespace units ;
2021-03-16 12:03:25 +01:00
using namespace units :: isq ;
using namespace units :: isq :: si ;
2019-11-06 16:50:34 +00:00
using namespace Catch :: Matchers ;
2019-10-16 17:04:41 +02:00
2019-11-05 20:05:11 +00:00
TEST_CASE ( "operator<< on a quantity" , "[text][ostream][fmt]" )
2019-10-16 17:04:41 +02:00
{
2020-03-19 09:23:27 +01:00
std :: ostringstream os ;
2019-10-16 17:04:41 +02:00
SECTION ( "quantity with a predefined unit" )
{
SECTION ( "integral representation" )
{
2020-09-09 19:20:35 +02:00
const auto q = 60 _q_W ;
2020-03-19 09:23:27 +01:00
os << q ;
2019-11-05 20:05:11 +00:00
SECTION ( "iostream" )
{
2020-03-19 09:23:27 +01:00
CHECK ( os . str () == "60 W" );
2019-11-05 20:05:11 +00:00
}
SECTION ( "fmt with default format {} on a quantity" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{}" , q ) == os . str ());
2019-11-05 20:05:11 +00:00
}
SECTION ( "fmt with format {:%Q %q} on a quantity" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{:%Q %q}" , q ) == os . str ());
2019-11-05 20:05:11 +00:00
}
2019-10-16 17:04:41 +02:00
}
SECTION ( "floating-point representation" )
{
2020-09-09 19:20:35 +02:00
const auto q = 1023.5 _q_Pa ;
2020-03-19 09:23:27 +01:00
os << q ;
2019-11-05 20:05:11 +00:00
SECTION ( "iostream" )
{
2020-03-19 09:23:27 +01:00
CHECK ( os . str () == "1023.5 Pa" );
2019-11-05 20:05:11 +00:00
}
SECTION ( "fmt with default format {} on a quantity" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{}" , q ) == os . str ());
2019-11-05 20:05:11 +00:00
}
SECTION ( "fmt with format {:%Q %q} on a quantity" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{:%Q %q}" , q ) == os . str ());
2019-11-05 20:05:11 +00:00
}
2019-10-16 17:04:41 +02:00
}
2019-11-04 06:37:50 +00:00
}
2019-10-18 15:34:46 +02:00
2019-11-09 21:01:37 +00:00
SECTION ( "quantity with a predefined prefixed unit" )
{
2020-09-09 19:20:35 +02:00
const auto q = 125 _q_us ;
2020-03-19 09:23:27 +01:00
os << q ;
2019-11-09 21:01:37 +00:00
SECTION ( "iostream" )
{
2020-03-19 09:23:27 +01:00
CHECK ( os . str () == "125 µs" );
2019-11-09 21:01:37 +00:00
}
SECTION ( "fmt with default format {} on a quantity" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{}" , q ) == os . str ());
2019-11-09 21:01:37 +00:00
}
SECTION ( "fmt with format {:%Q %q} on a quantity" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{:%Q %q}" , q ) == os . str ());
2019-11-09 21:01:37 +00:00
}
}
2019-11-04 06:37:50 +00:00
SECTION ( "quantity with a predefined unit + prefix" )
{
SECTION ( "in terms of base units" )
2019-10-18 15:34:46 +02:00
{
2020-06-27 19:15:46 +02:00
const length < scaled_unit < ratio ( 1 , 1 , 6 ), metre >> q ( 123 );
2020-03-19 09:23:27 +01:00
os << q ;
2019-11-05 20:05:11 +00:00
SECTION ( "iostream" )
{
2020-03-19 09:23:27 +01:00
CHECK ( os . str () == "123 Mm" );
2019-11-05 20:05:11 +00:00
}
SECTION ( "fmt with default format {} on a quantity" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{}" , q ) == os . str ());
2019-11-05 20:05:11 +00:00
}
SECTION ( "fmt with format {:%Q %q} on a quantity" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{:%Q %q}" , q ) == os . str ());
2019-11-05 20:05:11 +00:00
}
2019-10-18 15:34:46 +02:00
}
2019-11-04 06:37:50 +00:00
SECTION ( "in terms of derived units" )
{
2020-06-27 19:15:46 +02:00
const energy < scaled_unit < ratio ( 1 , 1 , - 2 ), joule >> q ( 60 );
2020-03-19 09:23:27 +01:00
os << q ;
2019-11-05 20:05:11 +00:00
SECTION ( "iostream" )
{
2020-03-19 09:23:27 +01:00
CHECK ( os . str () == "60 cJ" );
2019-11-05 20:05:11 +00:00
}
SECTION ( "fmt with default format {} on a quantity" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{}" , q ) == os . str ());
2019-11-05 20:05:11 +00:00
}
SECTION ( "fmt with format {:%Q %q} on a quantity" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{:%Q %q}" , q ) == os . str ());
2019-11-05 20:05:11 +00:00
}
2019-11-04 06:37:50 +00:00
}
}
2020-05-08 21:18:16 +02:00
SECTION ( "quantity with an alias unit" )
{
2020-09-09 19:20:35 +02:00
const auto q = 2 _q_l ;
2020-05-08 21:18:16 +02:00
os << q ;
SECTION ( "iostream" )
{
CHECK ( os . str () == "2 l" );
}
SECTION ( "fmt with default format {} on a quantity" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{}" , q ) == os . str ());
2020-05-08 21:18:16 +02:00
}
SECTION ( "fmt with format {:%Q %q} on a quantity" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{:%Q %q}" , q ) == os . str ());
2020-05-08 21:18:16 +02:00
}
}
SECTION ( "quantity with a prefixed alias unit" )
{
2020-09-09 19:20:35 +02:00
const auto q = 2 _q_ml ;
2020-05-08 21:18:16 +02:00
os << q ;
SECTION ( "iostream" )
{
CHECK ( os . str () == "2 ml" );
}
SECTION ( "fmt with default format {} on a quantity" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{}" , q ) == os . str ());
2020-05-08 21:18:16 +02:00
}
SECTION ( "fmt with format {:%Q %q} on a quantity" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{:%Q %q}" , q ) == os . str ());
2020-05-08 21:18:16 +02:00
}
}
2021-05-10 15:56:48 +02:00
SECTION ( "quantity with a derived unit" )
2019-11-04 06:37:50 +00:00
{
SECTION ( "coherent derived unit" )
{
SECTION ( "acceleration" )
{
2020-09-09 19:20:35 +02:00
const auto q = 20 _q_m / 2 _q_s / 1 _q_s ;
2020-03-19 09:23:27 +01:00
os << q ;
2019-11-05 20:05:11 +00:00
SECTION ( "iostream" )
{
2020-03-19 09:23:27 +01:00
CHECK ( os . str () == "10 m/s²" );
2019-11-05 20:05:11 +00:00
}
SECTION ( "fmt with default format {} on a quantity" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{}" , q ) == os . str ());
2019-11-05 20:05:11 +00:00
}
SECTION ( "fmt with format {:%Q %q} on a quantity" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{:%Q %q}" , q ) == os . str ());
2019-11-05 20:05:11 +00:00
}
2019-11-04 06:37:50 +00:00
}
SECTION ( "volume" )
{
2020-09-09 19:20:35 +02:00
const auto q = 2 _q_m * 1 _q_m * 1 _q_m ;
2020-03-19 09:23:27 +01:00
os << q ;
2019-11-05 20:05:11 +00:00
SECTION ( "iostream" )
{
2020-03-19 09:23:27 +01:00
CHECK ( os . str () == "2 m³" );
2019-11-05 20:05:11 +00:00
}
SECTION ( "fmt with default format {} on a quantity" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{}" , q ) == os . str ());
2019-11-05 20:05:11 +00:00
}
SECTION ( "fmt with format {:%Q %q} on a quantity" )
2019-11-10 19:51:25 +01:00
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{:%Q %q}" , q ) == os . str ());
2019-11-10 19:51:25 +01:00
}
}
SECTION ( "surface tension" )
{
2020-09-09 19:20:35 +02:00
const auto q = 20 _q_N / 2 _q_m ;
2020-03-19 09:23:27 +01:00
os << q ;
2019-11-10 19:51:25 +01:00
SECTION ( "iostream" )
{
2020-03-19 09:23:27 +01:00
CHECK ( os . str () == "10 N/m" );
2019-11-10 19:51:25 +01:00
}
SECTION ( "fmt with default format {} on a quantity" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{}" , q ) == os . str ());
2019-11-10 19:51:25 +01:00
}
SECTION ( "fmt with format {:%Q %q} on a quantity" )
2019-11-05 20:05:11 +00:00
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{:%Q %q}" , q ) == os . str ());
2019-11-05 20:05:11 +00:00
}
2019-11-04 06:37:50 +00:00
}
}
SECTION ( "deduced derived unit" )
{
2020-05-10 17:31:47 +02:00
SECTION ( "speed" )
2019-11-04 06:37:50 +00:00
{
2020-09-09 19:20:35 +02:00
const auto q = 20 _q_km / 2 _q_h ;
2020-03-19 09:23:27 +01:00
os << q ;
2019-11-05 20:05:11 +00:00
SECTION ( "iostream" )
{
2020-03-19 09:23:27 +01:00
CHECK ( os . str () == "10 km/h" );
2019-11-05 20:05:11 +00:00
}
SECTION ( "fmt with default format {} on a quantity" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{}" , q ) == os . str ());
2019-11-05 20:05:11 +00:00
}
SECTION ( "fmt with format {:%Q %q} on a quantity" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{:%Q %q}" , q ) == os . str ());
2019-11-05 20:05:11 +00:00
}
2019-11-04 06:37:50 +00:00
}
2019-11-04 06:46:53 +00:00
SECTION ( "surface tension" )
{
2021-05-10 15:56:48 +02:00
struct newton_per_centimetre : derived_unit < newton_per_centimetre , si :: dim_surface_tension , newton , centimetre > {};
2019-12-11 08:07:13 +01:00
const surface_tension < newton_per_centimetre > q ( 123 );
2020-03-19 09:23:27 +01:00
os << q ;
2019-11-05 20:05:11 +00:00
SECTION ( "iostream" )
{
2020-03-19 09:23:27 +01:00
CHECK ( os . str () == "123 N/cm" );
2019-11-05 20:05:11 +00:00
}
SECTION ( "fmt with default format {} on a quantity" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{}" , q ) == os . str ());
2019-11-05 20:05:11 +00:00
}
SECTION ( "fmt with format {:%Q %q} on a quantity" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{:%Q %q}" , q ) == os . str ());
2019-11-05 20:05:11 +00:00
}
2019-11-04 06:46:53 +00:00
}
2019-11-04 06:37:50 +00:00
}
2019-10-16 17:04:41 +02:00
}
SECTION ( "quantity with a predefined dimension but unknown unit" )
{
2019-10-17 10:16:44 +02:00
SECTION ( "unit::ratio as an SI prefix for a dimension with a special symbol" )
2019-10-16 17:04:41 +02:00
{
2020-09-09 19:20:35 +02:00
const auto q = 4 _q_N * 2 _q_cm ;
2020-03-19 09:23:27 +01:00
os << q ;
2019-11-05 20:05:11 +00:00
SECTION ( "iostream" )
{
2020-03-19 09:23:27 +01:00
CHECK ( os . str () == "8 cJ" );
2019-11-05 20:05:11 +00:00
}
SECTION ( "fmt with default format {} on a quantity" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{}" , q ) == os . str ());
2019-11-05 20:05:11 +00:00
}
SECTION ( "fmt with format {:%Q %q} on a quantity" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{:%Q %q}" , q ) == os . str ());
2019-11-05 20:05:11 +00:00
}
2019-10-16 17:04:41 +02:00
}
2019-10-17 10:16:44 +02:00
SECTION ( "unit::ratio for a dimension without a special symbol" )
{
2020-09-09 19:20:35 +02:00
const auto q = 2 _q_um * 2 _q_cm * 2 _q_cm ;
2020-03-19 09:23:27 +01:00
os << q ;
2019-11-05 20:05:11 +00:00
SECTION ( "iostream" )
{
2020-05-07 20:15:47 +03:00
CHECK ( os . str () == "8 × 10⁻¹⁰ m³" );
2019-11-05 20:05:11 +00:00
}
SECTION ( "fmt with default format {} on a quantity" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{}" , q ) == os . str ());
2019-11-05 20:05:11 +00:00
}
SECTION ( "fmt with format {:%Q %q} on a quantity" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{:%Q %q}" , q ) == os . str ());
2019-11-05 20:05:11 +00:00
}
2019-10-17 10:16:44 +02:00
}
2019-10-16 17:04:41 +02:00
SECTION ( "unit::ratio::num != 1 && unit::ratio::den == 1" )
{
2020-09-09 19:20:35 +02:00
const auto q = 4 * 2 _q_min / ( 2 _q_s * 2 _q_s );
2020-03-19 09:23:27 +01:00
os << q ;
2019-11-05 20:05:11 +00:00
SECTION ( "iostream" )
{
2020-03-19 09:23:27 +01:00
CHECK ( os . str () == "2 [6 × 10¹] Hz" );
2019-11-05 20:05:11 +00:00
}
SECTION ( "fmt with default format {} on a quantity" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{}" , q ) == os . str ());
2019-11-05 20:05:11 +00:00
}
SECTION ( "fmt with format {:%Q %q} on a quantity" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{:%Q %q}" , q ) == os . str ());
2019-11-05 20:05:11 +00:00
}
2019-10-16 17:04:41 +02:00
}
SECTION ( "unit::ratio::num == 1 && unit::ratio::den != 1" )
{
2020-09-09 19:20:35 +02:00
const auto q = 20 _q_J / 2 _q_min ;
2020-03-19 09:23:27 +01:00
os << q ;
2019-11-05 20:05:11 +00:00
SECTION ( "iostream" )
{
2020-03-19 09:23:27 +01:00
CHECK ( os . str () == "10 [1/6 × 10⁻¹] W" );
2019-11-05 20:05:11 +00:00
}
SECTION ( "fmt with default format {} on a quantity" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{}" , q ) == os . str ());
2019-11-05 20:05:11 +00:00
}
SECTION ( "fmt with format {:%Q %q} on a quantity" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{:%Q %q}" , q ) == os . str ());
2019-11-05 20:05:11 +00:00
}
2019-10-16 17:04:41 +02:00
}
SECTION ( "unit::ratio::num != 1 && unit::ratio::den != 1" )
{
2020-09-09 19:20:35 +02:00
const auto q = 60 _q_kJ / 2 _q_min ;
2020-03-19 09:23:27 +01:00
os << q ;
2019-11-05 20:05:11 +00:00
SECTION ( "iostream" )
{
2020-03-19 09:23:27 +01:00
CHECK ( os . str () == "30 [1/6 × 10²] W" );
2019-11-05 20:05:11 +00:00
}
SECTION ( "fmt with default format {} on a quantity" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{}" , q ) == os . str ());
2019-11-05 20:05:11 +00:00
}
SECTION ( "fmt with format {:%Q %q} on a quantity" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{:%Q %q}" , q ) == os . str ());
2019-11-05 20:05:11 +00:00
}
2019-10-16 17:04:41 +02:00
}
}
2020-09-08 11:02:16 +02:00
SECTION ( "dimensionless quantity" )
{
2020-09-09 11:20:55 +02:00
SECTION ( "one with ratio == 1" )
2020-09-08 11:02:16 +02:00
{
2020-09-09 19:20:35 +02:00
const auto q = 4 _q_m / 2 _q_m ;
2020-09-08 11:02:16 +02:00
os << q ;
SECTION ( "iostream" )
{
CHECK ( os . str () == "2" );
}
SECTION ( "fmt with default format {} on a quantity" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{}" , q ) == os . str ());
2020-09-08 11:02:16 +02:00
}
SECTION ( "fmt with format {:%Q %q} on a quantity" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{:%Q %q}" , q ) == "2 " );
2020-09-08 11:02:16 +02:00
}
}
2020-09-09 11:20:55 +02:00
SECTION ( "one with ratio.exp != 0" )
2020-09-08 11:02:16 +02:00
{
2020-09-09 19:20:35 +02:00
const auto q = 4 _q_km / 2 _q_m ;
2020-09-08 11:02:16 +02:00
os << q ;
SECTION ( "iostream" )
{
CHECK ( os . str () == "2 × 10³" );
}
SECTION ( "fmt with default format {} on a quantity" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{}" , q ) == os . str ());
2020-09-08 11:02:16 +02:00
}
SECTION ( "fmt with format {:%Q %q} on a quantity" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{:%Q %q}" , q ) == "2 × 10³" );
2020-09-08 11:02:16 +02:00
}
}
SECTION ( "percents" )
{
2020-09-13 18:45:46 +02:00
#if UNITS_DOWNCAST_MODE == 0
2020-09-10 13:01:38 +02:00
const auto q = quantity_cast < dim_one , percent > ( 15. _q_m / 100. _q_m );
2020-09-10 11:33:58 +02:00
#else
2020-09-09 19:20:35 +02:00
const auto q = quantity_cast < percent > ( 15. _q_m / 100. _q_m );
2020-09-10 11:33:58 +02:00
#endif
2020-09-08 11:02:16 +02:00
os << q ;
SECTION ( "iostream" )
{
CHECK ( os . str () == "15 %" );
}
SECTION ( "fmt with default format {} on a quantity" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{}" , q ) == os . str ());
2020-09-08 11:02:16 +02:00
}
SECTION ( "fmt with format {:%Q %q} on a quantity" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{:%Q %q}" , q ) == os . str ());
2020-09-08 11:02:16 +02:00
}
}
}
2019-10-16 17:04:41 +02:00
SECTION ( "quantity with an unkown dimension" )
{
SECTION ( "unit::ratio::num == 1 && unit::ratio::den == 1" )
{
2019-12-29 17:06:03 +01:00
SECTION ( "SI base units" )
2019-11-05 20:05:11 +00:00
{
2020-09-09 19:20:35 +02:00
const auto q = 2 _q_s * 2 _q_m * 2 _q_kg ;
2020-03-19 09:23:27 +01:00
os << q ;
2019-12-29 17:06:03 +01:00
SECTION ( "iostream" )
{
2020-03-27 00:19:56 +02:00
CHECK ( os . str () == "8 m ⋅ kg ⋅ s" );
2019-12-29 17:06:03 +01:00
}
SECTION ( "fmt with default format {} on a quantity" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{}" , q ) == os . str ());
2019-12-29 17:06:03 +01:00
}
SECTION ( "fmt with format {:%Q %q} on a quantity" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{:%Q %q}" , q ) == os . str ());
2019-12-29 17:06:03 +01:00
}
2019-11-05 20:05:11 +00:00
}
2019-12-29 17:06:03 +01:00
SECTION ( "CGS base units" )
2019-11-05 20:05:11 +00:00
{
2020-09-10 17:14:33 +02:00
const auto q = 2. _q_s * si :: cgs :: length < si :: cgs :: centimetre > ( 2 ) * si :: cgs :: mass < si :: cgs :: gram > ( 2 );
2020-03-19 09:23:27 +01:00
os << q ;
2019-11-05 20:05:11 +00:00
2019-12-29 17:06:03 +01:00
SECTION ( "iostream" )
{
2020-03-27 00:19:56 +02:00
CHECK ( os . str () == "8 cm ⋅ g ⋅ s" );
2019-12-29 17:06:03 +01:00
}
SECTION ( "fmt with default format {} on a quantity" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{}" , q ) == os . str ());
2019-12-29 17:06:03 +01:00
}
SECTION ( "fmt with format {:%Q %q} on a quantity" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{:%Q %q}" , q ) == os . str ());
2019-12-29 17:06:03 +01:00
}
2019-11-05 20:05:11 +00:00
}
2019-10-16 17:04:41 +02:00
}
SECTION ( "unit::ratio as an SI prefix" )
{
2020-09-09 19:20:35 +02:00
const auto q = 4 _q_km * 2 _q_s ;
2020-03-19 09:23:27 +01:00
os << q ;
2019-11-05 20:05:11 +00:00
SECTION ( "iostream" )
{
2020-03-27 00:19:56 +02:00
CHECK ( os . str () == "8 × 10³ m ⋅ s" );
2019-11-05 20:05:11 +00:00
}
SECTION ( "fmt with default format {} on a quantity" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{}" , q ) == os . str ());
2019-11-05 20:05:11 +00:00
}
SECTION ( "fmt with format {:%Q %q} on a quantity" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{:%Q %q}" , q ) == os . str ());
2019-11-05 20:05:11 +00:00
}
2019-10-16 17:04:41 +02:00
}
SECTION ( "unit::ratio::num != 1 && unit::ratio::den == 1" )
{
2020-09-09 19:20:35 +02:00
const auto q = 4 _q_kg * 2 _q_min / ( 2 _q_s * 2 _q_s );
2020-03-19 09:23:27 +01:00
os << q ;
2019-11-05 20:05:11 +00:00
SECTION ( "iostream" )
{
2020-03-19 09:23:27 +01:00
CHECK ( os . str () == "2 [6 × 10¹] kg/s" );
2019-11-05 20:05:11 +00:00
}
SECTION ( "fmt with default format {} on a quantity" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{}" , q ) == os . str ());
2019-11-05 20:05:11 +00:00
}
SECTION ( "fmt with format {:%Q %q} on a quantity" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{:%Q %q}" , q ) == os . str ());
2019-11-05 20:05:11 +00:00
}
2019-10-16 17:04:41 +02:00
}
SECTION ( "unit::ratio::num == 1 && unit::ratio::den != 1" )
{
2020-09-09 19:20:35 +02:00
const auto q = 20 _q_kg / 2 _q_min ;
2020-03-19 09:23:27 +01:00
os << q ;
2019-11-05 20:05:11 +00:00
SECTION ( "iostream" )
{
2020-03-19 09:23:27 +01:00
CHECK ( os . str () == "10 [1/6 × 10⁻¹] kg/s" );
2019-11-05 20:05:11 +00:00
}
SECTION ( "fmt with default format {} on a quantity" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{}" , q ) == os . str ());
2019-11-05 20:05:11 +00:00
}
SECTION ( "fmt with format {:%Q %q} on a quantity" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{:%Q %q}" , q ) == os . str ());
2019-11-05 20:05:11 +00:00
}
2019-10-16 17:04:41 +02:00
}
2020-05-05 21:26:30 +02:00
SECTION ( "CGS base units" )
{
2020-09-10 17:14:33 +02:00
const auto q = 2. _q_s * si :: cgs :: length < si :: metre > ( 2 ) * si :: cgs :: mass < si :: kilogram > ( 2 );
2020-05-05 21:26:30 +02:00
os << q ;
SECTION ( "iostream" )
2019-12-29 17:06:03 +01:00
{
2020-05-05 21:26:30 +02:00
CHECK ( os . str () == "8 × 10⁵ cm ⋅ g ⋅ s" );
2019-12-29 17:06:03 +01:00
}
2020-05-05 21:26:30 +02:00
SECTION ( "fmt with default format {} on a quantity" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{}" , q ) == os . str ());
2020-05-05 21:26:30 +02:00
}
SECTION ( "fmt with format {:%Q %q} on a quantity" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{:%Q %q}" , q ) == os . str ());
2020-05-05 21:26:30 +02:00
}
}
2019-10-16 17:04:41 +02:00
SECTION ( "unit::ratio::num != 1 && unit::ratio::den != 1" )
{
2020-09-09 19:20:35 +02:00
const auto q = 60 _q_min / 2 _q_km ;
2020-03-19 09:23:27 +01:00
os << q ;
2019-11-05 20:05:11 +00:00
SECTION ( "iostream" )
{
2020-03-27 00:19:56 +02:00
CHECK ( os . str () == "30 [6 × 10⁻²] 1/m ⋅ s" );
2019-11-05 20:05:11 +00:00
}
SECTION ( "fmt with default format {} on a quantity" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{}" , q ) == os . str ());
2019-11-05 20:05:11 +00:00
}
SECTION ( "fmt with format {:%Q %q} on a quantity" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{:%Q %q}" , q ) == os . str ());
2019-11-05 20:05:11 +00:00
}
2019-10-16 17:04:41 +02:00
}
2020-09-08 11:02:16 +02:00
SECTION ( "exponent::num == 1 && exponent::den == 1" )
2019-10-16 17:04:41 +02:00
{
2020-09-09 19:20:35 +02:00
const auto q = 4 _q_m * 2 _q_s ;
2020-03-19 09:23:27 +01:00
os << q ;
2019-11-05 20:05:11 +00:00
SECTION ( "iostream" )
{
2020-03-27 00:19:56 +02:00
CHECK ( os . str () == "8 m ⋅ s" );
2019-11-05 20:05:11 +00:00
}
SECTION ( "fmt with default format {} on a quantity" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{}" , q ) == os . str ());
2019-11-05 20:05:11 +00:00
}
SECTION ( "fmt with format {:%Q %q} on a quantity" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{:%Q %q}" , q ) == os . str ());
2019-11-05 20:05:11 +00:00
}
2019-10-16 17:04:41 +02:00
}
2020-09-08 11:02:16 +02:00
SECTION ( "exponent::num == 2 && exponent::den == 1 for positive exponent" )
2019-10-16 17:04:41 +02:00
{
2020-09-09 19:20:35 +02:00
const auto q = 4 _q_m * 2 _q_s * 2 _q_s ;
2020-03-19 09:23:27 +01:00
os << q ;
2019-11-05 20:05:11 +00:00
SECTION ( "iostream" )
{
2020-03-27 00:19:56 +02:00
CHECK ( os . str () == "16 m ⋅ s²" );
2019-11-05 20:05:11 +00:00
}
SECTION ( "fmt with default format {} on a quantity" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{}" , q ) == os . str ());
2019-11-05 20:05:11 +00:00
}
SECTION ( "fmt with format {:%Q %q} on a quantity" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{:%Q %q}" , q ) == os . str ());
2019-11-05 20:05:11 +00:00
}
2019-10-16 17:04:41 +02:00
}
2020-09-08 11:02:16 +02:00
SECTION ( "exponent::num == 2 && exponent::den == 1 for negative exponent (first dimension)" )
2019-10-16 17:04:41 +02:00
{
2020-09-09 19:20:35 +02:00
const auto q = 8 _q_s / 2 _q_m / 2 _q_m ;
2020-03-19 09:23:27 +01:00
os << q ;
2019-11-05 20:05:11 +00:00
SECTION ( "iostream" )
{
2020-03-27 00:19:56 +02:00
CHECK ( os . str () == "2 1/m² ⋅ s" );
2019-11-05 20:05:11 +00:00
}
SECTION ( "fmt with default format {} on a quantity" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{}" , q ) == os . str ());
2019-11-05 20:05:11 +00:00
}
SECTION ( "fmt with format {:%Q %q} on a quantity" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{:%Q %q}" , q ) == os . str ());
2019-11-05 20:05:11 +00:00
}
2019-10-16 17:04:41 +02:00
}
2020-09-08 11:02:16 +02:00
SECTION ( "exponent::num == 2 && exponent::den == 1 for negative exponent (not first dimension)" )
2019-10-16 17:04:41 +02:00
{
2020-09-09 19:20:35 +02:00
const auto q = 8 _q_m / 2 _q_kg / 2 _q_kg ;
2020-03-19 09:23:27 +01:00
os << q ;
2019-11-05 20:05:11 +00:00
SECTION ( "iostream" )
{
2020-03-19 09:23:27 +01:00
CHECK ( os . str () == "2 m/kg²" );
2019-11-05 20:05:11 +00:00
}
SECTION ( "fmt with default format {} on a quantity" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{}" , q ) == os . str ());
2019-11-05 20:05:11 +00:00
}
SECTION ( "fmt with format {:%Q %q} on a quantity" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{:%Q %q}" , q ) == os . str ());
2019-11-05 20:05:11 +00:00
}
2019-10-16 17:04:41 +02:00
}
SECTION ( "fractional positive exponent" )
{
2020-09-09 19:20:35 +02:00
const auto q = sqrt ( 9 _q_m );
2020-03-19 09:23:27 +01:00
os << q ;
2019-11-05 20:05:11 +00:00
SECTION ( "iostream" )
{
2020-03-19 09:23:27 +01:00
CHECK ( os . str () == "3 m^(1/2)" );
2019-11-05 20:05:11 +00:00
}
SECTION ( "fmt with default format {} on a quantity" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{}" , q ) == os . str ());
2019-11-05 20:05:11 +00:00
}
SECTION ( "fmt with format {:%Q %q} on a quantity" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{:%Q %q}" , q ) == os . str ());
2019-11-05 20:05:11 +00:00
}
2019-10-16 17:04:41 +02:00
}
SECTION ( "fractional negative exponent" )
{
2020-09-09 19:20:35 +02:00
const auto q = sqrt ( 9 / 1 _q_m );
2020-03-19 09:23:27 +01:00
os << q ;
2019-10-16 17:04:41 +02:00
2019-11-05 20:05:11 +00:00
SECTION ( "iostream" )
{
2020-03-19 09:23:27 +01:00
CHECK ( os . str () == "3 1/m^(1/2)" );
2019-11-05 20:05:11 +00:00
}
2019-10-18 23:50:43 +02:00
2019-11-05 20:05:11 +00:00
SECTION ( "fmt with default format {} on a quantity" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{}" , q ) == os . str ());
2019-11-05 20:05:11 +00:00
}
2019-10-18 23:50:43 +02:00
2019-11-05 20:05:11 +00:00
SECTION ( "fmt with format {:%Q %q} on a quantity" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{:%Q %q}" , q ) == os . str ());
2019-11-05 20:05:11 +00:00
}
2019-10-18 23:50:43 +02:00
}
}
}
2019-10-16 17:04:41 +02:00
2019-11-06 16:50:34 +00:00
TEST_CASE ( "format string with only %Q should print quantity value only" , "[text][fmt]" )
{
SECTION ( "integral representation" )
{
2019-11-06 22:45:45 +00:00
SECTION ( "positive value" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{:%Q}" , 123 _q_km_per_h ) == "123" );
2019-11-06 22:45:45 +00:00
}
SECTION ( "negative value" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{:%Q}" , 5 _q_m - 10 _q_m ) == "-5" );
2019-11-06 22:45:45 +00:00
}
2019-11-06 16:50:34 +00:00
}
SECTION ( "floating-point representation" )
{
2019-11-06 22:45:45 +00:00
SECTION ( "positive value" )
2019-11-06 16:50:34 +00:00
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{:%Q}" , 221. _q_km / 2 _q_h ) == "110.5" );
2019-11-06 16:50:34 +00:00
}
2019-11-06 22:45:45 +00:00
SECTION ( "negative value" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{:%Q}" , 3.14 _q_m - 10 _q_m ) == "-6.86" );
2019-11-06 22:45:45 +00:00
}
SECTION ( "nan" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{:%Q}" , length < metre > ( std :: numeric_limits < double >:: quiet_NaN ())) == "nan" );
2019-11-06 22:45:45 +00:00
}
SECTION ( "inf" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{:%Q}" , length < metre > ( std :: numeric_limits < double >:: infinity ())) == "inf" );
2019-11-06 22:45:45 +00:00
}
SECTION ( "-inf" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{:%Q}" , length < metre > ( - std :: numeric_limits < double >:: infinity ())) == "-inf" );
2019-11-06 22:45:45 +00:00
}
2019-11-06 16:50:34 +00:00
}
}
TEST_CASE ( "format string with only %q should print quantity unit symbol only" , "[text][fmt]" )
{
2020-05-05 21:26:30 +02:00
SECTION ( "standard format for a unit without Unicode symbols" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{:%q}" , 123 _q_km_per_h ) == "km/h" );
2020-05-05 21:26:30 +02:00
}
2019-11-06 16:50:34 +00:00
2020-05-05 21:26:30 +02:00
SECTION ( "ASCII format for a unit without Unicode symbols" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{:%Aq}" , 123 _q_km_per_h ) == "km/h" );
2020-05-05 21:26:30 +02:00
}
2020-03-24 06:59:25 +02:00
2020-05-05 21:26:30 +02:00
SECTION ( "standard format for a unit with Unicode symbols" )
{
SECTION ( "Unicode signs in a unit symbol" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{:%q}" , 123 _q_kR ) == "kΩ" );
2020-05-05 21:26:30 +02:00
}
2020-03-24 06:59:25 +02:00
2020-05-05 21:26:30 +02:00
SECTION ( "Unicode signs in a unit symbol prefix" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{:%q}" , 123 _q_uV ) == "µV" );
2020-05-05 21:26:30 +02:00
}
}
2020-03-24 06:59:25 +02:00
2020-05-05 21:26:30 +02:00
SECTION ( "ASCII format for a unit with Unicode symbols" )
{
SECTION ( "Unicode signs in a unit symbol" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{:%Aq}" , 123 _q_kR ) == "kohm" );
2020-05-05 21:26:30 +02:00
}
2020-03-25 09:06:45 +02:00
2020-05-05 21:26:30 +02:00
SECTION ( "Unicode signs in a unit symbol prefix" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{:%Aq}" , 123 _q_uV ) == "uV" );
2020-05-05 21:26:30 +02:00
}
}
2020-03-25 09:06:45 +02:00
}
2020-03-24 06:59:25 +02:00
TEST_CASE ( "%q and %Q can be put anywhere in a format string" , "[text][fmt]" )
2019-11-06 16:50:34 +00:00
{
SECTION ( "no space" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{:%Q%q}" , 123 _q_km_per_h ) == "123km/h" );
2019-11-06 16:50:34 +00:00
}
SECTION ( "separator" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{:%Q###%q}" , 123 _q_km_per_h ) == "123###km/h" );
2019-11-06 16:50:34 +00:00
}
SECTION ( "opposite order" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{:%q %Q}" , 123 _q_km_per_h ) == "km/h 123" );
2019-11-06 16:50:34 +00:00
}
2019-11-06 21:52:48 +00:00
SECTION ( "tabulator" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{:%Q%t%q}" , 123 _q_km_per_h ) == "123 \t km/h" );
2019-11-06 21:52:48 +00:00
}
SECTION ( "new line" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{:%Q%n%q}" , 123 _q_km_per_h ) == "123 \n km/h" );
2019-11-06 21:52:48 +00:00
}
2019-11-06 22:45:45 +00:00
SECTION ( "% sign" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{:%Q%% %q}" , 123 _q_km_per_h ) == "123% km/h" );
2019-11-06 22:45:45 +00:00
}
2019-11-06 16:50:34 +00:00
}
2020-03-19 09:23:27 +01:00
TEST_CASE ( "fill and align specification" , "[text][fmt][ostream]" )
2019-11-12 16:55:11 +01:00
{
2020-03-19 09:23:27 +01:00
SECTION ( "ostream" )
{
std :: ostringstream os ;
SECTION ( "width = 10" )
{
2020-09-09 19:20:35 +02:00
os << "|" << std :: setw ( 10 ) << 123 _q_m << "|" ;
2020-03-19 09:23:27 +01:00
CHECK ( os . str () == "| 123 m|" );
}
SECTION ( "width = 10, align = right" )
{
2020-09-09 19:20:35 +02:00
os << "|" << std :: setw ( 10 ) << std :: right << 123 _q_m << "|" ;
2020-03-19 09:23:27 +01:00
CHECK ( os . str () == "| 123 m|" );
}
SECTION ( "width = 10, align = left" )
{
2020-09-09 19:20:35 +02:00
os << "|" << std :: setw ( 10 ) << std :: left << 123 _q_m << "|" ;
2020-03-19 09:23:27 +01:00
CHECK ( os . str () == "|123 m |" );
}
SECTION ( "width = 10, fill = *" )
{
2020-09-09 19:20:35 +02:00
os << "|" << std :: setw ( 10 ) << std :: setfill ( '*' ) << 123 _q_m << "|" ;
2020-03-19 09:23:27 +01:00
CHECK ( os . str () == "|*****123 m|" );
}
SECTION ( "width = 10, fill = *, align = right" )
{
2020-09-09 19:20:35 +02:00
os << "|" << std :: setw ( 10 ) << std :: setfill ( '*' ) << std :: right << 123 _q_m << "|" ;
2020-03-19 09:23:27 +01:00
CHECK ( os . str () == "|*****123 m|" );
}
SECTION ( "width = 10, fill = *, align = left" )
{
2020-09-09 19:20:35 +02:00
os << "|" << std :: setw ( 10 ) << std :: setfill ( '*' ) << std :: left << 123 _q_m << "|" ;
2020-03-19 09:23:27 +01:00
CHECK ( os . str () == "|123 m*****|" );
}
}
2019-12-27 18:49:43 +00:00
SECTION ( "default format {} on a quantity" )
2019-11-12 16:55:11 +01:00
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "|{:0}|" , 123 _q_m ) == "|123 m|" );
CHECK ( STD_FMT :: format ( "|{:10}|" , 123 _q_m ) == "| 123 m|" );
CHECK ( STD_FMT :: format ( "|{:<10}|" , 123 _q_m ) == "|123 m |" );
CHECK ( STD_FMT :: format ( "|{:>10}|" , 123 _q_m ) == "| 123 m|" );
CHECK ( STD_FMT :: format ( "|{:^10}|" , 123 _q_m ) == "| 123 m |" );
CHECK ( STD_FMT :: format ( "|{:*<10}|" , 123 _q_m ) == "|123 m*****|" );
CHECK ( STD_FMT :: format ( "|{:*>10}|" , 123 _q_m ) == "|*****123 m|" );
CHECK ( STD_FMT :: format ( "|{:*^10}|" , 123 _q_m ) == "|**123 m***|" );
2019-11-12 16:55:11 +01:00
}
SECTION ( "full format {:%Q %q} on a quantity" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "|{:0%Q%q}|" , 123 _q_m ) == "|123m|" );
CHECK ( STD_FMT :: format ( "|{:10%Q%q}|" , 123 _q_m ) == "| 123m|" );
CHECK ( STD_FMT :: format ( "|{:<10%Q%q}|" , 123 _q_m ) == "|123m |" );
CHECK ( STD_FMT :: format ( "|{:>10%Q%q}|" , 123 _q_m ) == "| 123m|" );
CHECK ( STD_FMT :: format ( "|{:^10%Q%q}|" , 123 _q_m ) == "| 123m |" );
CHECK ( STD_FMT :: format ( "|{:*<10%Q%q}|" , 123 _q_m ) == "|123m******|" );
CHECK ( STD_FMT :: format ( "|{:*>10%Q%q}|" , 123 _q_m ) == "|******123m|" );
CHECK ( STD_FMT :: format ( "|{:*^10%Q%q}|" , 123 _q_m ) == "|***123m***|" );
2019-11-12 16:55:11 +01:00
}
2019-12-27 18:49:43 +00:00
SECTION ( "value only format {:%Q} on a quantity" )
2019-11-12 16:55:11 +01:00
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "|{:0%Q}|" , 123 _q_m ) == "|123|" );
CHECK ( STD_FMT :: format ( "|{:10%Q}|" , 123 _q_m ) == "| 123|" );
CHECK ( STD_FMT :: format ( "|{:<10%Q}|" , 123 _q_m ) == "|123 |" );
CHECK ( STD_FMT :: format ( "|{:>10%Q}|" , 123 _q_m ) == "| 123|" );
CHECK ( STD_FMT :: format ( "|{:^10%Q}|" , 123 _q_m ) == "| 123 |" );
CHECK ( STD_FMT :: format ( "|{:*<10%Q}|" , 123 _q_m ) == "|123*******|" );
CHECK ( STD_FMT :: format ( "|{:*>10%Q}|" , 123 _q_m ) == "|*******123|" );
CHECK ( STD_FMT :: format ( "|{:*^10%Q}|" , 123 _q_m ) == "|***123****|" );
2019-11-12 16:55:11 +01:00
}
2019-12-27 18:49:43 +00:00
SECTION ( "symbol only format {:%q} on a quantity" )
2019-11-12 16:55:11 +01:00
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "|{:0%q}|" , 123 _q_m ) == "|m|" );
CHECK ( STD_FMT :: format ( "|{:10%q}|" , 123 _q_m ) == "|m |" );
CHECK ( STD_FMT :: format ( "|{:<10%q}|" , 123 _q_m ) == "|m |" );
CHECK ( STD_FMT :: format ( "|{:>10%q}|" , 123 _q_m ) == "| m|" );
CHECK ( STD_FMT :: format ( "|{:^10%q}|" , 123 _q_m ) == "| m |" );
CHECK ( STD_FMT :: format ( "|{:*<10%q}|" , 123 _q_m ) == "|m*********|" );
CHECK ( STD_FMT :: format ( "|{:*>10%q}|" , 123 _q_m ) == "|*********m|" );
CHECK ( STD_FMT :: format ( "|{:*^10%q}|" , 123 _q_m ) == "|****m*****|" );
2019-11-12 16:55:11 +01:00
}
}
TEST_CASE ( "sign specification" , "[text][fmt]" )
{
2019-12-11 08:07:13 +01:00
length < metre > inf ( std :: numeric_limits < double >:: infinity ());
length < metre > nan ( std :: numeric_limits < double >:: quiet_NaN ());
2019-11-12 16:55:11 +01:00
2019-12-27 18:49:43 +00:00
SECTION ( "full format {:%Q %q} on a quantity" )
2019-11-12 16:55:11 +01:00
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{0:%Q%q},{0:%+Q%q},{0:%-Q%q},{0:% Q%q}" , 1 _q_m ) == "1m,+1m,1m, 1m" );
CHECK ( STD_FMT :: format ( "{0:%Q%q},{0:%+Q%q},{0:%-Q%q},{0:% Q%q}" , - 1 _q_m ) == "-1m,-1m,-1m,-1m" );
CHECK ( STD_FMT :: format ( "{0:%Q%q},{0:%+Q%q},{0:%-Q%q},{0:% Q%q}" , inf ) == "infm,+infm,infm, infm" );
CHECK ( STD_FMT :: format ( "{0:%Q%q},{0:%+Q%q},{0:%-Q%q},{0:% Q%q}" , nan ) == "nanm,+nanm,nanm, nanm" );
2019-11-12 16:55:11 +01:00
}
2019-12-27 18:49:43 +00:00
SECTION ( "value only format {:%Q} on a quantity" )
2019-11-12 16:55:11 +01:00
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{0:%Q},{0:%+Q},{0:%-Q},{0:% Q}" , 1 _q_m ) == "1,+1,1, 1" );
CHECK ( STD_FMT :: format ( "{0:%Q},{0:%+Q},{0:%-Q},{0:% Q}" , - 1 _q_m ) == "-1,-1,-1,-1" );
CHECK ( STD_FMT :: format ( "{0:%Q},{0:%+Q},{0:%-Q},{0:% Q}" , inf ) == "inf,+inf,inf, inf" );
CHECK ( STD_FMT :: format ( "{0:%Q},{0:%+Q},{0:%-Q},{0:% Q}" , nan ) == "nan,+nan,nan, nan" );
2019-11-12 16:55:11 +01:00
}
}
2019-11-06 16:50:34 +00:00
TEST_CASE ( "precision specification" , "[text][fmt]" )
{
2019-12-27 18:49:43 +00:00
SECTION ( "full format {:%Q %q} on a quantity" )
2019-11-06 16:50:34 +00:00
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{:%.0Q %q}" , 1.2345 _q_m ) == "1 m" );
CHECK ( STD_FMT :: format ( "{:%.1Q %q}" , 1.2345 _q_m ) == "1.2 m" );
CHECK ( STD_FMT :: format ( "{:%.2Q %q}" , 1.2345 _q_m ) == "1.23 m" );
2021-03-15 21:13:21 +01:00
#ifdef UNITS_COMP_MSVC
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{:%.3Q %q}" , 1.2345 _q_m ) == "1.234 m" );
2020-09-05 22:54:57 +02:00
#else
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{:%.3Q %q}" , 1.2345 _q_m ) == "1.235 m" );
2020-09-05 22:54:57 +02:00
#endif
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{:%.4Q %q}" , 1.2345 _q_m ) == "1.2345 m" );
CHECK ( STD_FMT :: format ( "{:%.5Q %q}" , 1.2345 _q_m ) == "1.23450 m" );
CHECK ( STD_FMT :: format ( "{:%.10Q %q}" , 1.2345 _q_m ) == "1.2345000000 m" );
2019-11-06 16:50:34 +00:00
}
2019-12-27 18:49:43 +00:00
SECTION ( "value only format {:%Q} on a quantity" )
2019-11-06 16:50:34 +00:00
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{:%.0Q}" , 1.2345 _q_m ) == "1" );
CHECK ( STD_FMT :: format ( "{:%.1Q}" , 1.2345 _q_m ) == "1.2" );
CHECK ( STD_FMT :: format ( "{:%.2Q}" , 1.2345 _q_m ) == "1.23" );
2021-03-15 21:13:21 +01:00
#ifdef UNITS_COMP_MSVC
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{:%.3Q}" , 1.2345 _q_m ) == "1.234" );
2020-09-05 22:54:57 +02:00
#else
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{:%.3Q}" , 1.2345 _q_m ) == "1.235" );
2020-09-05 22:54:57 +02:00
#endif
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{:%.4Q}" , 1.2345 _q_m ) == "1.2345" );
CHECK ( STD_FMT :: format ( "{:%.5Q}" , 1.2345 _q_m ) == "1.23450" );
CHECK ( STD_FMT :: format ( "{:%.10Q}" , 1.2345 _q_m ) == "1.2345000000" );
2019-11-06 16:50:34 +00:00
}
}
TEST_CASE ( "precision specification for integral representation should throw" , "[text][fmt][exception]" )
{
2019-12-27 18:49:43 +00:00
SECTION ( "full format {:%Q %q} on a quantity" )
2019-11-06 16:50:34 +00:00
{
2021-11-08 19:05:08 +01:00
REQUIRE_THROWS_MATCHES ( STD_FMT :: vformat ( "{:%.1Q %q}" , STD_FMT :: make_format_args ( 1 _q_m )), STD_FMT :: format_error , Message ( "precision not allowed for integral quantity representation" ));
2019-11-06 16:50:34 +00:00
}
2019-12-27 18:49:43 +00:00
SECTION ( "value only format {:%Q} on a quantity" )
2019-11-06 16:50:34 +00:00
{
2021-11-08 19:05:08 +01:00
REQUIRE_THROWS_MATCHES ( STD_FMT :: vformat ( "{:%.1Q}" , STD_FMT :: make_format_args ( 1 _q_m )), STD_FMT :: format_error , Message ( "precision not allowed for integral quantity representation" ));
2019-11-06 16:50:34 +00:00
}
}
2020-03-18 00:59:49 +01:00
TEST_CASE ( "type specification" , "[text][fmt]" )
{
SECTION ( "full format {:%Q %q} on a quantity" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{:%bQ %q}" , 42 _q_m ) == "101010 m" );
CHECK ( STD_FMT :: format ( "{:%BQ %q}" , 42 _q_m ) == "101010 m" );
CHECK ( STD_FMT :: format ( "{:%dQ %q}" , 42 _q_m ) == "42 m" );
CHECK ( STD_FMT :: format ( "{:%oQ %q}" , 42 _q_m ) == "52 m" );
CHECK ( STD_FMT :: format ( "{:%xQ %q}" , 42 _q_m ) == "2a m" );
CHECK ( STD_FMT :: format ( "{:%XQ %q}" , 42 _q_m ) == "2A m" );
2020-03-18 00:59:49 +01:00
2021-03-15 21:13:21 +01:00
#ifdef UNITS_COMP_MSVC
2021-11-15 17:41:02 +01:00
#if UNITS_USE_LIBFMT
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{:%aQ %q}" , 1.2345678 _q_m ) == "0x1.3c0ca2a5b1d5dp+0 m" );
CHECK ( STD_FMT :: format ( "{:%.3aQ %q}" , 1.2345678 _q_m ) == "0x1.3c1p+0 m" );
CHECK ( STD_FMT :: format ( "{:%AQ %q}" , 1.2345678 _q_m ) == "0X1.3C0CA2A5B1D5DP+0 m" );
CHECK ( STD_FMT :: format ( "{:%.3AQ %q}" , 1.2345678 _q_m ) == "0X1.3C1P+0 m" );
2021-11-15 16:36:09 +01:00
#else
CHECK ( STD_FMT :: format ( "{:%aQ %q}" , 1.2345678 _q_m ) == "1.3c0ca2a5b1d5dp+0 m" );
CHECK ( STD_FMT :: format ( "{:%.3aQ %q}" , 1.2345678 _q_m ) == "1.3c1p+0 m" );
CHECK ( STD_FMT :: format ( "{:%AQ %q}" , 1.2345678 _q_m ) == "1.3C0CA2A5B1D5DP+0 m" );
CHECK ( STD_FMT :: format ( "{:%.3AQ %q}" , 1.2345678 _q_m ) == "1.3C1P+0 m" );
2021-11-15 17:41:02 +01:00
#endif // UNITS_USE_LIBFMT
2020-09-05 22:54:57 +02:00
#else
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{:%aQ %q}" , 1.2345678 _q_m ) == "0x9.e065152d8eae841p-3 m" );
CHECK ( STD_FMT :: format ( "{:%.3aQ %q}" , 1.2345678 _q_m ) == "0x9.e06p-3 m" );
CHECK ( STD_FMT :: format ( "{:%AQ %q}" , 1.2345678 _q_m ) == "0X9.E065152D8EAE841P-3 m" );
CHECK ( STD_FMT :: format ( "{:%.3AQ %q}" , 1.2345678 _q_m ) == "0X9.E06P-3 m" );
2020-09-05 22:54:57 +02:00
#endif
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{:%eQ %q}" , 1.2345678 _q_m ) == "1.234568e+00 m" );
CHECK ( STD_FMT :: format ( "{:%.3eQ %q}" , 1.2345678 _q_m ) == "1.235e+00 m" );
CHECK ( STD_FMT :: format ( "{:%EQ %q}" , 1.2345678 _q_m ) == "1.234568E+00 m" );
CHECK ( STD_FMT :: format ( "{:%.3EQ %q}" , 1.2345678 _q_m ) == "1.235E+00 m" );
CHECK ( STD_FMT :: format ( "{:%gQ %q}" , 1.2345678 _q_m ) == "1.23457 m" );
CHECK ( STD_FMT :: format ( "{:%gQ %q}" , 1.2345678e8 _q_m ) == "1.23457e+08 m" );
CHECK ( STD_FMT :: format ( "{:%.3gQ %q}" , 1.2345678 _q_m ) == "1.23 m" );
CHECK ( STD_FMT :: format ( "{:%.3gQ %q}" , 1.2345678e8 _q_m ) == "1.23e+08 m" );
CHECK ( STD_FMT :: format ( "{:%GQ %q}" , 1.2345678 _q_m ) == "1.23457 m" );
CHECK ( STD_FMT :: format ( "{:%GQ %q}" , 1.2345678e8 _q_m ) == "1.23457E+08 m" );
CHECK ( STD_FMT :: format ( "{:%.3GQ %q}" , 1.2345678 _q_m ) == "1.23 m" );
CHECK ( STD_FMT :: format ( "{:%.3GQ %q}" , 1.2345678e8 _q_m ) == "1.23E+08 m" );
2020-03-18 00:59:49 +01:00
}
SECTION ( "value only format {:%Q} on a quantity" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{:%bQ}" , 42 _q_m ) == "101010" );
CHECK ( STD_FMT :: format ( "{:%BQ}" , 42 _q_m ) == "101010" );
CHECK ( STD_FMT :: format ( "{:%dQ}" , 42 _q_m ) == "42" );
CHECK ( STD_FMT :: format ( "{:%oQ}" , 42 _q_m ) == "52" );
CHECK ( STD_FMT :: format ( "{:%xQ}" , 42 _q_m ) == "2a" );
CHECK ( STD_FMT :: format ( "{:%XQ}" , 42 _q_m ) == "2A" );
2020-03-18 00:59:49 +01:00
2021-03-15 21:13:21 +01:00
#ifdef UNITS_COMP_MSVC
2021-11-15 17:12:44 +01:00
#if UNITS_USE_LIBFMT
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{:%aQ}" , 1.2345678 _q_m ) == "0x1.3c0ca2a5b1d5dp+0" );
CHECK ( STD_FMT :: format ( "{:%.3aQ}" , 1.2345678 _q_m ) == "0x1.3c1p+0" );
CHECK ( STD_FMT :: format ( "{:%AQ}" , 1.2345678 _q_m ) == "0X1.3C0CA2A5B1D5DP+0" );
CHECK ( STD_FMT :: format ( "{:%.3AQ}" , 1.2345678 _q_m ) == "0X1.3C1P+0" );
2021-11-15 16:36:09 +01:00
#else
CHECK ( STD_FMT :: format ( "{:%aQ}" , 1.2345678 _q_m ) == "1.3c0ca2a5b1d5dp+0" );
CHECK ( STD_FMT :: format ( "{:%.3aQ}" , 1.2345678 _q_m ) == "1.3c1p+0" );
CHECK ( STD_FMT :: format ( "{:%AQ}" , 1.2345678 _q_m ) == "1.3C0CA2A5B1D5DP+0" );
CHECK ( STD_FMT :: format ( "{:%.3AQ}" , 1.2345678 _q_m ) == "1.3C1P+0" );
2021-11-15 17:12:44 +01:00
#endif // UNITS_USE_LIBFMT
2020-09-05 22:54:57 +02:00
#else
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{:%aQ}" , 1.2345678 _q_m ) == "0x9.e065152d8eae841p-3" );
CHECK ( STD_FMT :: format ( "{:%.3aQ}" , 1.2345678 _q_m ) == "0x9.e06p-3" );
CHECK ( STD_FMT :: format ( "{:%AQ}" , 1.2345678 _q_m ) == "0X9.E065152D8EAE841P-3" );
CHECK ( STD_FMT :: format ( "{:%.3AQ}" , 1.2345678 _q_m ) == "0X9.E06P-3" );
2020-09-05 22:54:57 +02:00
#endif
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{:%eQ}" , 1.2345678 _q_m ) == "1.234568e+00" );
CHECK ( STD_FMT :: format ( "{:%.3eQ}" , 1.2345678 _q_m ) == "1.235e+00" );
CHECK ( STD_FMT :: format ( "{:%EQ}" , 1.2345678 _q_m ) == "1.234568E+00" );
CHECK ( STD_FMT :: format ( "{:%.3EQ}" , 1.2345678 _q_m ) == "1.235E+00" );
CHECK ( STD_FMT :: format ( "{:%gQ}" , 1.2345678 _q_m ) == "1.23457" );
CHECK ( STD_FMT :: format ( "{:%gQ}" , 1.2345678e8 _q_m ) == "1.23457e+08" );
CHECK ( STD_FMT :: format ( "{:%.3gQ}" , 1.2345678 _q_m ) == "1.23" );
CHECK ( STD_FMT :: format ( "{:%.3gQ}" , 1.2345678e8 _q_m ) == "1.23e+08" );
CHECK ( STD_FMT :: format ( "{:%GQ}" , 1.2345678 _q_m ) == "1.23457" );
CHECK ( STD_FMT :: format ( "{:%GQ}" , 1.2345678e8 _q_m ) == "1.23457E+08" );
CHECK ( STD_FMT :: format ( "{:%.3GQ}" , 1.2345678 _q_m ) == "1.23" );
CHECK ( STD_FMT :: format ( "{:%.3GQ}" , 1.2345678e8 _q_m ) == "1.23E+08" );
2020-03-18 00:59:49 +01:00
}
}
2020-09-10 01:31:42 +02:00
TEST_CASE ( "different base types with the # specifier" , "[text][fmt]" )
2020-03-18 00:59:49 +01:00
{
SECTION ( "full format {:%Q %q} on a quantity" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{:%#bQ %q}" , 42 _q_m ) == "0b101010 m" );
CHECK ( STD_FMT :: format ( "{:%#BQ %q}" , 42 _q_m ) == "0B101010 m" );
CHECK ( STD_FMT :: format ( "{:%#oQ %q}" , 42 _q_m ) == "052 m" );
CHECK ( STD_FMT :: format ( "{:%#xQ %q}" , 42 _q_m ) == "0x2a m" );
CHECK ( STD_FMT :: format ( "{:%#XQ %q}" , 42 _q_m ) == "0X2A m" );
2020-03-18 00:59:49 +01:00
}
SECTION ( "value only format {:%Q} on a quantity" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( "{:%#bQ}" , 42 _q_m ) == "0b101010" );
CHECK ( STD_FMT :: format ( "{:%#BQ}" , 42 _q_m ) == "0B101010" );
CHECK ( STD_FMT :: format ( "{:%#oQ}" , 42 _q_m ) == "052" );
CHECK ( STD_FMT :: format ( "{:%#xQ}" , 42 _q_m ) == "0x2a" );
CHECK ( STD_FMT :: format ( "{:%#XQ}" , 42 _q_m ) == "0X2A" );
2020-03-18 00:59:49 +01:00
}
}
2019-10-18 15:34:46 +02:00
2020-09-10 01:31:42 +02:00
TEST_CASE ( "localization with the 'L' specifier" , "[text][fmt][localization]" )
{
struct group2 : std :: numpunct < char >
{
2020-09-10 01:37:31 +02:00
char do_thousands_sep () const override { return '_' ; }
std :: string do_grouping () const override { return " \2 " ; }
2020-09-10 01:31:42 +02:00
};
struct group3 : std :: numpunct < char >
{
2020-09-10 01:37:31 +02:00
char do_thousands_sep () const override { return '\'' ; }
std :: string do_grouping () const override { return " \3 " ; }
2020-09-10 01:31:42 +02:00
};
std :: locale grp2 { std :: locale :: classic (), new group2 };
std :: locale grp3 { std :: locale :: classic (), new group3 };
SECTION ( "full format {:%LQ %q} on a quantity" )
{
2021-09-20 15:01:58 +02:00
CHECK ( STD_FMT :: format ( grp2 , "{:%LQ %q}" , 299792458 _q_m_per_s ) == "2_99_79_24_58 m/s" );
CHECK ( STD_FMT :: format ( grp3 , "{:%LQ %q}" , 299792458 _q_m_per_s ) == "299'792'458 m/s" );
2020-09-10 01:31:42 +02:00
}
}
2019-12-23 13:22:37 +01:00
TEST_CASE ( "quantity_cast" , "[text][ostream]" )
{
2020-03-19 09:23:27 +01:00
std :: ostringstream os ;
2019-12-23 13:22:37 +01:00
SECTION ( "int to double representation" )
{
2020-09-09 19:20:35 +02:00
const auto q = 121 _q_km / 2 _q_h ;
2019-12-23 13:22:37 +01:00
SECTION ( "original" )
{
2020-03-19 09:23:27 +01:00
os << q ;
CHECK ( os . str () == "60 km/h" );
2019-12-23 13:22:37 +01:00
}
SECTION ( "int" )
{
2020-03-19 09:23:27 +01:00
os << quantity_cast < int > ( q );
CHECK ( os . str () == "60 km/h" );
2019-12-23 13:22:37 +01:00
}
SECTION ( "double" )
{
2020-03-19 09:23:27 +01:00
os << quantity_cast < double > ( q );
CHECK ( os . str () == "60 km/h" );
2019-12-23 13:22:37 +01:00
}
}
SECTION ( "double to int representation" )
{
2020-09-09 19:20:35 +02:00
const auto q = 121. _q_km / 2 _q_h ;
2019-12-23 13:22:37 +01:00
SECTION ( "original" )
{
2020-03-19 09:23:27 +01:00
os << q ;
CHECK ( os . str () == "60.5 km/h" );
2019-12-23 13:22:37 +01:00
}
SECTION ( "int" )
{
2020-03-19 09:23:27 +01:00
os << quantity_cast < int > ( q );
CHECK ( os . str () == "60 km/h" );
2019-12-23 13:22:37 +01:00
}
SECTION ( "double" )
{
2020-03-19 09:23:27 +01:00
os << quantity_cast < double > ( q );
CHECK ( os . str () == "60.5 km/h" );
2019-12-23 13:22:37 +01:00
}
}
}