Skip to content

You are annoyed by the long compilation time when you use fmt lib. Now your code will take even longer to compile, and programs will run even faster.

License

Notifications You must be signed in to change notification settings

uselessgoddess/constexpr-format

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

30 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

constexpr-format

You are annoyed by the long compilation time when you use fmt lib. Now your code will take even longer to compile, and programs will run even faster.

Getting started

Hello world

#include <format.h> // include full library 

namespace fmt = constexpr_format; // short namespace alias 
using namespace fmt::literals; // for use ""_fmt literal

int main()
{
    std::cout << fmt::format("Hello {}!"_fmt, "world") << std::endl;
    fmt::print("Hello {}!\n"_fmt, "world");
    fmt::println("Hello {}!"_fmt, "world");
    
    // also can use
    // fmt::print("Hello world!\n"_fmt);
}

Is this true at compile time?

Yeah?!

#include <format.h> // include full library 

namespace fmt = constexpr_format; // short namespace alias 
using namespace fmt::literals; // for use ""_fmt literal

int main()
{
    fmt::println("Hello {}!"_fmt, "world", "lol"); // static assertion failed
    fmt::println("Hello {}!"_fmt); // static assertion failed
    fmt::println("Hello { }!"_fmt, "world"); // static assertion failed
    fmt::println("Hello {!"_fmt, "world"); // static assertion failed

    fmt::println("Hello {1}!"_fmt, "hello world");
    fmt::println("{0} {0}!"_fmt, "Hello", "world");
    // and others
}

Convert custom types to string

std::string operator

#include <format.h>

namespace fmt = constexpr_format;
using namespace fmt::literals;

struct string_wrapper
{
    std::string str;
    explicit operator std::string() const noexcept
    {
        return str;
    }
};

int main()
{
    // it's javascript?
    fmt::print(R"("{}" + "{}" == "{}")"_fmt, string_wrapper{"1"}, string_wrapper{"2"}, string_wrapper{"12"});
}

operator<< for ostream

#include <format.h>

template<typename T1, typename T2>
struct pair
{
    T1 first;
    T2 second;

    friend auto& operator<<(std::ostream& stream, pair<T1, T2> pair) {
        stream << "(" << pair.first << ", " << pair.second << ")";
        return stream;
    }
};

template<typename T1, typename T2>
pair(T1, T2) -> pair<T1, T2>;

int main()
{
    namespace fmt = constexpr_format;
    using namespace fmt::literals;

    fmt::print("{0} + {1} == {1} + {0} == {2}"_fmt, 
    /* #0 */   pair{1, 2}, 
    /* #1 */   pair{2, 1}, 
    /* #2 */   pair{3, 3});
}

temporary built in converting

#include <format.h>

namespace fmt = constexpr_format;
using namespace fmt::literals;

template<fmt::formatable T1, fmt::formatable T2>
struct fmt::string_converter<std::pair<T1, T2>>
{
    std::string operator()(const std::pair<T1, T2> pair) const noexcept ( /* after creating noexcept integral conversion in new version */ )
    {
        return fmt::format("({}, {})"_fmt, pair.first, pair.second);        
    }
};

Performance

About

You are annoyed by the long compilation time when you use fmt lib. Now your code will take even longer to compile, and programs will run even faster.

Topics

Resources

License

Stars

Watchers

Forks

Languages