All Projects → robhz786 → strf

robhz786 / strf

Licence: BSL-1.0 license
Yet another C++ text formatting library.

Programming Languages

C++
36643 projects - #6 most used programming language

Projects that are alternatives of or similar to strf

cmake-init
The missing CMake project initializer
Stars: ✭ 1,071 (+1778.95%)
Mutual labels:  static-library
vue-i18n
A small package for implementing translations in Vue.js
Stars: ✭ 40 (-29.82%)
Mutual labels:  i18n
awesome-i18n
🌍 A curated list of i18n resources for all kind of languages and frameworks
Stars: ✭ 205 (+259.65%)
Mutual labels:  i18n
laminas-i18n
Provide translations for your application, and filter and validate internationalized values
Stars: ✭ 40 (-29.82%)
Mutual labels:  i18n
ad localize
ADLocalize is a simple way to manage your localization files. Supported wording sources : CSVs and Google Sheets. Localization file generation available for iOS, Android, JSON (i18next), YAML and Java properties
Stars: ✭ 22 (-61.4%)
Mutual labels:  i18n
universal-react-starter-kit
Universal React Starter Kit is an universal web application framework using koa, react, redux and webpack.
Stars: ✭ 13 (-77.19%)
Mutual labels:  i18n
Vue Element Admin
🎉 A magical vue admin https://panjiachen.github.io/vue-element-admin
Stars: ✭ 73,044 (+128047.37%)
Mutual labels:  i18n
Foxy
🦊 A very, very cute, multipurpose, multilingual bot for Discord! Making your server cuter -w-
Stars: ✭ 58 (+1.75%)
Mutual labels:  i18n
MQCMS-admin
MQCMS后台管理系统
Stars: ✭ 24 (-57.89%)
Mutual labels:  i18n
doorkeeper-i18n
Translation files for Doorkeeper OAuth 2 provider
Stars: ✭ 30 (-47.37%)
Mutual labels:  i18n
alternate
Plug and Phoenix helpers to localize your web app via the URL
Stars: ✭ 26 (-54.39%)
Mutual labels:  i18n
translations
i18n translations of Revolt
Stars: ✭ 27 (-52.63%)
Mutual labels:  i18n
react-mobx-router
Create React App with React Router 4 and MobX + Internationalization
Stars: ✭ 90 (+57.89%)
Mutual labels:  i18n
laravel-adminer
Adminer database management tool for your Laravel application.
Stars: ✭ 45 (-21.05%)
Mutual labels:  i18n
poeditor-cli
POEditor CLI
Stars: ✭ 29 (-49.12%)
Mutual labels:  i18n
wrap
📖⏎ An efficient and flexible word-wrapping package for Go (golang)
Stars: ✭ 14 (-75.44%)
Mutual labels:  text-formatting
asgi-babel
Adds internationalization (i18n) support to ASGI applications (Asyncio/Trio)
Stars: ✭ 21 (-63.16%)
Mutual labels:  i18n
typesafe-i18n
A fully type-safe and lightweight internationalization library for all your TypeScript and JavaScript projects.
Stars: ✭ 1,227 (+2052.63%)
Mutual labels:  i18n
cakephp-i18n
A CakePHP plugin with I18n related tools.
Stars: ✭ 40 (-29.82%)
Mutual labels:  i18n
example-app
Example app showcasing fulls1z3's Angular libraries
Stars: ✭ 27 (-52.63%)
Mutual labels:  i18n

Strf

Build Status codecov

Strf is a C++11 text formatting library that

Attention : Branch master was renamed to main at the time of release 0.15.0.

Documentation

Requirements

Strf has been tested in the following compilers:

  • Clang 3.8.1
  • GCC 6.3.0
  • Visual Studio 2019 16
  • NVCC 11.0

Examples

Basic examples

#include <strf/to_string.hpp>
#include <assert>

constexpr int x = 255;

void basic_samples()
{
    // Creating a std::string
    auto str = strf::to_string(x, " in hexadecimal is ", *strf::hex(x), '.');
    assert("255 in hexadecimal is 0xff.");

    // Alternative syntax to enable i18n
    auto str_tr = strf::to_string.tr("{} in hexadecimal is {}.", x, *strf::hex(x));
    assert(str_tr == str);

    // Applying a facet
    auto to_string_mc = strf::to_string.with(strf::mixedcase);
    auto str_mc = to_string_mc(x, " in hexadecimal is ", *strf::hex(x), '.');
    assert(str_mc == "255 in hexadecimal is 0xFF.");

    // Achieving the same result, but in multiple steps:
    strf::string_maker str_maker;
    strf::to(str_maker) (x, " in hexadecimal is ");
    strf::to(str_maker).with(strf::mixedcase) (*strf::hex(x), '.');
    auto str_mc_2 = str_maker.finish();
    assert(str_mc_2 == str_mc);

    // Writing instead to char*
    char buff[200];
    strf::to(buff, sizeof(buff)) (x, " in hexadecimal is ", *strf::hex(x), '.');
    assert(str == buff);
}

Alignment formatting

#include <strf/to_string.hpp>
#include <assert>

void alignment_formatting()
{
    using namespace strf::format_functions;

    assert(strf::to_string(dec(123) > 8)  == "     123");
    assert(strf::to_string(dec(123) < 8)  == "123     ");
    assert(strf::to_string(dec(123) ^ 8)  == "  123   ");

    assert(strf::to_string(right(123, 8))        == "     123");
    assert(strf::to_string(right(123, 8,  '~'))  == "~~~~~123");
    assert(strf::to_string(left(123, 8,  '~'))   == "123~~~~~");
    assert(strf::to_string(center(123, 8,  '~')) == "~~123~~~");

    assert(strf::to_u8string(right(123, 8, U'')) == u8"‥‥‥‥‥123");
}

Note: Strf calculates string width the same way it is specified to std::format, which takes grapheme clustering into account.

Single character argument

#include <strf/to_string.hpp>
#include <assert>

void single_character_argument()
{
    using namespace strf::format_functions; // strf::multi, strf::right

    assert(strf::to_string('a') == "a");
    assert(strf::to_string(multi('a', 5)) == "aaaaa");
    assert(strf::to_string(multi('a', 5) > 8) == "   aaaaa");
    assert(strf::to_string(right('a', 8, '.').multi(5)) == "...aaaaa");

    // char32_t is implicitly transcoded
    assert(strf::to_string(U'a') == "a");
    assert(strf::to_u8string(U'\u2022') == u8"");
    assert(strf::to_u8string(multi(U'\u2022', 5) > 8) == u8"   •••••");

    // strf::to_string(L'a') // doesn't compile: it must be char32_t or
                             // the same as the destination character type
}

Numeric Formmating

#include <strf/to_string.hpp>
#include <numbers> // C++20, defines std::numbers::pi
#include <assert>

void numeric_formatting()
{
    using namespace strf::format_functions;

    //  In printf  |       In Strf
    //-------------+-----------------------
    //         Integers
    //-------------+-----------------------
    //      'd'    |   .dec() or dec(value)
    //      'o'    |   .oct() or oct(value)
    //      'x'    |   .hex() or hex(value)
    //             |   .bin() or bin(value)
    //-------------+-----------------------
    //      Floating Points
    //-------------+-----------------------
    //      'x'    |   hex(value).p(6) or   hex(value, 6)
    //      'f'    | fixed(value).p(6) or fixed(value, 6)
    //    'e' 'E'  |   sci(value).p(6) or   sci(value, 6)
    //      'g'    |   gen(value).p(6) or   gen(value, 6)
    //-------------+-----------------------
    //   Integers and Floating Points
    //-------------+-----------------------
    //      '+'    |    .operator+()
    //      '#'    |    .operator*()
    //      ' '    |    .operator~()
    //  .precision |    .p(precision), or as the second argument of
    //             |                 hex(), fixed(), sci() or gen()
    //      '0'    |    .pad0(width) or pad0(value, width)

    assert(strf::to_string(  fmt(1.)) == "1");
    assert(strf::to_string( *fmt(1.)) == "1.");
    assert(strf::to_string( +fmt(1.)) == "+1");
    assert(strf::to_string(+*fmt(1.)) == "+1.");
    assert(strf::to_string( ~fmt(1.5)) == " 1.5");
    assert(strf::to_string( ~left(1.5, 8, '*')) == "*1.5****");

    assert(strf::to_string(sci(1.0))     == "1e+00");
    assert(strf::to_string(fixed(1e+10)) == "10000000000");

    //----------------------------------------------------------------
    // Strf prints enough digits for exact recovery on parsing
    // regardless of notation
    using std::numbers::pi;
    assert(strf::to_string(fixed(pi)) == "3.141592653589793");

    // , unless a precision is specified
    assert(strf::to_string(fixed(pi).p(4)) == "3.1416");
    assert(strf::to_string(fixed(pi, 4))   == "3.1416");
    assert(strf::to_string(gen(pi, 4))     == "3.142");

    // ---------------------------------------------------------------
    // pad0()
    assert(strf::to_string(+*pad0(1., 5))     == "+001.");
    assert(strf::to_string(+*pad0(1., 5) > 8) == "   +001.");

    // For nan and inf, pad0 sets the minimum alignment width:
    constexpr auto nan = std::numeric_limits<double>::quiet_NaN();
    assert(strf::to_string(pad0(nan, 8))              == "     nan");
    assert(strf::to_string(left(nan, 4, '*').pad0(8)) == "nan*****");
    assert(strf::to_string(left(nan, 8, '*').pad0(4)) == "nan*****");

    //----------------------------------------------------------------
    // The strf::lettercase facet
    constexpr auto to_string_upper = strf::to_string.with(strf::uppercase);
    constexpr auto to_string_lower = strf::to_string.with(strf::lowercase); // default
    constexpr auto to_string_mixed = strf::to_string.with(strf::mixedcase);

    assert(to_string_upper(*hex(0xaa), " ", sci(1.)) == "0XAA 1E+00");
    assert(to_string_lower(*hex(0xaa), " ", sci(1.)) == "0xaa 1e+00");
    assert(to_string_mixed(*hex(0xaa), " ", sci(1.)) == "0xAA 1e+00");
}

Numeric Punctuation

#include <strf/to_string.hpp>
#include <strf/locale.hpp> // strf::locale_numpunct

void numeric_punctuation()
{
    // German punctuation
    auto s = strf::to_string.with(strf::numpunct_de_DE) (!strf::fixed(1000000.5));
    assert(s == "1.000.000,5");

    // You have to use format function `strf::punct` or `.punct()`
    // or operator! to apply punctuation
    s = strf::to_string.with(strf::numpunct_de_DE)
        ( !strf::fixed(1000000.5), "  ", strf::fixed(1000000.5)
        , "  ", strf::punct(10000), "  ", 100000 );
    assert(s == "1.000.000,5  1000000.5  10.000  100000");

    // Extracting punctuation from locale
    if (setlocale(LC_NUMERIC, "as_IN")) {
        auto loc_punct = strf::locale_numpunct(); // provided by header <strf/locale.hpp>
        auto s_loc = strf::to_string.with(loc_punct) (*!strf::fixed(1e+16));
        assert(s_loc == "10,00,00,00,00,00,00,000.");
    }

    // Manually specifing a punctuation
    constexpr auto my_fancy_punct = strf::numpunct<10>(3)
        .thousands_sep(U'')
        .decimal_point(U''); // U+2396
    auto s2 = strf::to_u8string.with(my_fancy_punct) (!strf::fixed(1000000.5));
    assert(s2 == u8"1•000•000⎖5");

    // With variable grouping
    constexpr auto my_fancy_punct_2 = strf::numpunct<10>(3, 2, 1)
        .thousands_sep(U'')
        .decimal_point(U'');
    auto s3 = strf::to_u8string.with(my_fancy_punct_2)
        (strf::punct(10000000.125));
    assert(s3 == u8"1•0•0•00•000⎖125");

    // Non-decimal bases
    constexpr auto my_hex_punct = strf::numpunct<16>(4).thousands_sep('\'');
    auto s4 = strf::to_string.with(my_hex_punct)(!strf::hex(0xFFFFFFF));
    assert(s4 == "fff'ffff");
}

Transcoding

#include <strf/to_string.hpp>

void transcoding()
{
    // Converting UTF-16 to UTF-8
    auto str_narrow = strf::to_string("He was born in ", strf::conv(u"خنيفرة"), '.');
    assert(str_narrow == "He was born in \xd8\xae\xd9\x86\xd9\x8a\xd9\x81\xd8\xb1\xd8\xa9.");

    auto str_u8 = strf::to_u8string(u8"He was born in ", strf::conv(u"خنيفرة"), u8'.');
    assert(str_u8 == u8"He was born in خنيفرة.");


    // Converting UTF-8 to UTF-16
    assert(strf::to_u16string(strf::conv(str_narrow)) == u"He was born in خنيفرة.");
    assert(strf::to_u16string(strf::conv(str_u8)) == u"He was born in خنيفرة.");


    // Converting UTF-16 to ISO-8859-6
    auto str_narrow_2 = strf::to_string.with(strf::iso_8859_6<char>)
        ( "He was born in ", strf::conv(u"خنيفرة"), '.');
    assert(str_narrow_2 == "He was born in \xce\xe6\xea\xe1\xd1\xc9.");


    // Converting char8_t string to ISO-8859-6
    auto str_narrow_3 = strf::to_string.with(strf::iso_8859_6<char>)
        ( "He was born in ", strf::conv(u8"خنيفرة"), '.');
    assert(str_narrow_3 == str_narrow_2);


    // Converting UTF-8 to ISO-8859-6
    // ( if the source character type is the same as the destination
    //   character type, the charset must be specified inside strf::conv() )
    auto str_narrow_4 = strf::to_string.with(strf::iso_8859_6<char>)
        ( "He was born in "
        , strf::conv("\xd8\xae\xd9\x86\xd9\x8a\xd9\x81\xd8\xb1\xd8\xa9", strf::utf8<char>)
        , '.' );
    assert(str_narrow_4 == str_narrow_2);


    // Converting ISO-8859-6 to UTF-16
    auto str_u16 = strf::to_u16string
        ( u"He was born in "
        , strf::conv("\xce\xe6\xea\xe1\xd1\xc9", strf::iso_8859_6<char>)
        , u'.' );
    assert(str_u16 == u"He was born in خنيفرة.");

    // or
    str_u16 = strf::to_u16string.with(strf::iso_8859_6<char>)
        ( u"He was born in "
        , strf::conv("\xce\xe6\xea\xe1\xd1\xc9")
        , u'.' );
    assert(str_u16 == u"He was born in خنيفرة.");


    // Several transcodings in a single statemet
    auto str = strf::to_u8string( strf::conv(u"aaa--")
                                , strf::conv(U"bbb--")
                                , strf::conv( "\x80\xA4"
                                            , strf::windows_1252<char> ) );
    assert(str == u8"aaa--bbb--\u20AC\u00A4");
}

Joining arguments

#include <strf/to_string.hpp>

void joins()
{
    // strf::join makes a sequence of arguments to be treated as one
    const char* dirname = "/tmp";
    const char* filename = "tmp1234";
    auto s = strf::to_string.tr( "Could not open file {}"
                               , strf::join(dirname, '/', filename) );

    assert(s == "Could not open file /tmp/tmp1234");


    // join_left, join_center and join_right align several arguments as one
    const int value = 255;
    s = strf::to_string( strf::join_center(40, U'.')( value
                                                    , " in hexadecimal is "
                                                    , strf::hex(value) ) );
    assert(s == "........255 in hexadecimal is ff........");


    // You can also use operators < > ^ to a align a join
    auto j = strf::join(value, " in hexadecimal is ", strf::hex(value));
    s = strf::to_string(j ^ 40);
    assert(s == "        255 in hexadecimal is ff        ");
}

Ranges

#include <strf/to_string.hpp>

void ranges()
{
    int array[] = {10, 20, 30, 40};

    // Basic
    auto str = strf::to_string( "--[", strf::range(array), "]--");
    assert(str == "--[10203040]--");


    // With separator
    str = strf::to_string( "--[", strf::separated_range(array, " / "), "]--");
    assert(str == "--[10 / 20 / 30 / 40]--");


    // With separator and formatting
    str = strf::to_string( "--["
                         , *strf::hex(strf::separated_range(array, " / ")).p(4)
                         , "]--");
    assert(str == "--[0x000a / 0x0014 / 0x001e / 0x0028]--");


    // Transforming the elements
    auto func = [](int x){ return strf::join('<', strf::pad0(x, 4), '>'); };

    str = strf::to_string(strf::range(array, func));
    assert(str == "<0010><0020><0030><0040>");

    str = strf::to_string(strf::separated_range(array, " ", func));
    assert(str == "<0010> <0020> <0030> <0040>");
}
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].