| 237 | |
| 238 | template <UnitEnum E, typename T> |
| 239 | static std::string valueToStringImpl( T value, const UnitToStringParams<E>& params ) |
| 240 | { |
| 241 | // If `str` starts with ASCII minus minus, and `params.unicodeMinusSign` is set, replace it with a Unicode minus sign. |
| 242 | // Also strips the minus from negative zeroes if `params.allowNegativeZero` is false. |
| 243 | auto adjustMinusSign = [&]( std::string& str ) |
| 244 | { |
| 245 | auto onlyZeroes = [&]{ return std::all_of( str.begin(), str.end(), []( char ch ){ return bool( std::isdigit( (unsigned char)ch ) ) <=/*implies*/ ( ch == '0' ); } ); }; |
| 246 | |
| 247 | switch ( params.zeroMode ) |
| 248 | { |
| 249 | case ZeroMode::asIs: |
| 250 | // Nothing. |
| 251 | break; |
| 252 | case ZeroMode::alwaysPositive: |
| 253 | // If the only digits in `str` are zeroes and we don't allow negative zeroes, remove the minus sign. |
| 254 | if ( str.starts_with( '-' ) && onlyZeroes() ) |
| 255 | str.erase( str.begin() ); |
| 256 | break; |
| 257 | case ZeroMode::alwaysNegative: |
| 258 | // If the only digits in `str` are zeroes and we don't allow positive zeroes, force the minus sign. |
| 259 | if ( !str.starts_with( '-' ) && onlyZeroes() ) |
| 260 | str.insert( str.begin(), '-' ); |
| 261 | break; |
| 262 | } |
| 263 | |
| 264 | // If there's no minus sign, add the plus sign. |
| 265 | if ( params.plusSign && !str.starts_with( '-' ) ) |
| 266 | str.insert( str.begin(), '+' ); |
| 267 | |
| 268 | // Replace the plain `-` sign with the fancy Unicode one. |
| 269 | if ( params.unicodeMinusSign && str.starts_with( '-' ) ) |
| 270 | { |
| 271 | // U+2212 MINUS SIGN. |
| 272 | str[0] = '\xe2'; |
| 273 | str.insert( str.begin() + 1, { '\x88', '\x92' } ); |
| 274 | } |
| 275 | }; |
| 276 | |
| 277 | // `str` is a value representing arcseconds or arcminutes. |
| 278 | // 1. Pads it with zeroes on the left to have at least two digits before the point. |
| 279 | // 2. Removes the leading minus, if any. (It should only be possible for the negative zero.) |
| 280 | auto adjustArcMinutesOrSeconds = [&]( std::string& str ) |
| 281 | { |
| 282 | if ( str.starts_with( '-' ) ) |
| 283 | str.erase( str.begin() ); |
| 284 | if ( std::isdigit( (unsigned char)str[0] ) && !std::isdigit( (unsigned char)str[1] ) ) |
| 285 | str = '0' + std::move( str ); |
| 286 | }; |
| 287 | |
| 288 | std::string unitSuffix; |
| 289 | if ( params.unitSuffix ) |
| 290 | { |
| 291 | if ( params.targetUnit ) |
| 292 | unitSuffix = s_tr( getUnitInfo( *params.targetUnit ).unitSuffix ); |
| 293 | else if ( params.sourceUnit ) |
| 294 | unitSuffix = s_tr( getUnitInfo( *params.sourceUnit ).unitSuffix ); |
| 295 | } |
| 296 | std::string ret; |