diff --git a/astyle.sh b/astyle.sh index 0e2b999d..6ccae55d 100755 --- a/astyle.sh +++ b/astyle.sh @@ -1,5 +1,5 @@ #!/bin/bash find . -name "*\.h" -o -name "*\.cpp"|xargs dos2unix -find . -name "*\.h" -o -name "*\.cpp"|xargs astyle -n -A1 +find . -name "*\.h" -o -name "*\.cpp"|xargs astyle -n -c -t4 -A1 diff --git a/bench/boost-bench-mt.cpp b/bench/boost-bench-mt.cpp index 24967fe6..cc7d75b5 100644 --- a/bench/boost-bench-mt.cpp +++ b/bench/boost-bench-mt.cpp @@ -18,17 +18,17 @@ namespace keywords = boost::log::keywords; void init() { - logging::add_file_log - ( - keywords::file_name = "logs/boost-sample_%N.log", /*< file name pattern >*/ - keywords::auto_flush = false, - keywords::format = "[%TimeStamp%]: %Message%" - ); + logging::add_file_log + ( + keywords::file_name = "logs/boost-sample_%N.log", /*< file name pattern >*/ + keywords::auto_flush = false, + keywords::format = "[%TimeStamp%]: %Message%" + ); - logging::core::get()->set_filter - ( - logging::trivial::severity >= logging::trivial::info - ); + logging::core::get()->set_filter + ( + logging::trivial::severity >= logging::trivial::info + ); } @@ -37,43 +37,43 @@ using namespace std; int main(int argc, char* argv[]) { - int thread_count = 10; - if(argc > 1) - thread_count = atoi(argv[1]); + int thread_count = 10; + if(argc > 1) + thread_count = atoi(argv[1]); - int howmany = 1000000; + int howmany = 1000000; - init(); - logging::add_common_attributes(); + init(); + logging::add_common_attributes(); - using namespace logging::trivial; + using namespace logging::trivial; - src::severity_logger_mt< severity_level > lg; + src::severity_logger_mt< severity_level > lg; - std::atomic msg_counter {0}; - vector threads; + std::atomic msg_counter {0}; + vector threads; - for (int t = 0; t < thread_count; ++t) - { - threads.push_back(std::thread([&]() - { - while (true) - { - int counter = ++msg_counter; - if (counter > howmany) break; - BOOST_LOG_SEV(lg, info) << "boost message #" << counter << ": This is some text for your pleasure"; - } - })); - } + for (int t = 0; t < thread_count; ++t) + { + threads.push_back(std::thread([&]() + { + while (true) + { + int counter = ++msg_counter; + if (counter > howmany) break; + BOOST_LOG_SEV(lg, info) << "boost message #" << counter << ": This is some text for your pleasure"; + } + })); + } - for(auto &t:threads) - { - t.join(); - }; + for(auto &t:threads) + { + t.join(); + }; - return 0; + return 0; } diff --git a/bench/boost-bench.cpp b/bench/boost-bench.cpp index 576a2ee0..75c2133f 100644 --- a/bench/boost-bench.cpp +++ b/bench/boost-bench.cpp @@ -15,30 +15,30 @@ namespace keywords = boost::log::keywords; void init() { - logging::add_file_log - ( - keywords::file_name = "logs/boost-sample_%N.log", /*< file name pattern >*/ - keywords::auto_flush = false, - keywords::format = "[%TimeStamp%]: %Message%" - ); + logging::add_file_log + ( + keywords::file_name = "logs/boost-sample_%N.log", /*< file name pattern >*/ + keywords::auto_flush = false, + keywords::format = "[%TimeStamp%]: %Message%" + ); - logging::core::get()->set_filter - ( - logging::trivial::severity >= logging::trivial::info - ); + logging::core::get()->set_filter + ( + logging::trivial::severity >= logging::trivial::info + ); } int main(int argc, char* []) { - int howmany = 1000000; - init(); - logging::add_common_attributes(); + int howmany = 1000000; + init(); + logging::add_common_attributes(); - using namespace logging::trivial; - src::severity_logger_mt< severity_level > lg; - for(int i = 0 ; i < howmany; ++i) - BOOST_LOG_SEV(lg, info) << "boost message #" << i << ": This is some text for your pleasure"; + using namespace logging::trivial; + src::severity_logger_mt< severity_level > lg; + for(int i = 0 ; i < howmany; ++i) + BOOST_LOG_SEV(lg, info) << "boost message #" << i << ": This is some text for your pleasure"; - return 0; + return 0; } diff --git a/bench/easylogging-bench-mt.cpp b/bench/easylogging-bench-mt.cpp index edea2103..412117cb 100644 --- a/bench/easylogging-bench-mt.cpp +++ b/bench/easylogging-bench-mt.cpp @@ -11,37 +11,37 @@ using namespace std; int main(int argc, char* argv[]) { - int thread_count = 10; - if(argc > 1) - thread_count = atoi(argv[1]); + int thread_count = 10; + if(argc > 1) + thread_count = atoi(argv[1]); - int howmany = 1000000; + int howmany = 1000000; - // Load configuration from file - el::Configurations conf("easyl.conf"); - el::Loggers::reconfigureLogger("default", conf); + // Load configuration from file + el::Configurations conf("easyl.conf"); + el::Loggers::reconfigureLogger("default", conf); - std::atomic msg_counter {0}; - vector threads; + std::atomic msg_counter {0}; + vector threads; - for (int t = 0; t < thread_count; ++t) - { - threads.push_back(std::thread([&]() - { - while (true) - { - int counter = ++msg_counter; - if (counter > howmany) break; - LOG(INFO) << "easylog message #" << counter << ": This is some text for your pleasure"; - } - })); - } + for (int t = 0; t < thread_count; ++t) + { + threads.push_back(std::thread([&]() + { + while (true) + { + int counter = ++msg_counter; + if (counter > howmany) break; + LOG(INFO) << "easylog message #" << counter << ": This is some text for your pleasure"; + } + })); + } - for(auto &t:threads) - { - t.join(); - }; + for(auto &t:threads) + { + t.join(); + }; - return 0; + return 0; } diff --git a/bench/easylogging-bench.cpp b/bench/easylogging-bench.cpp index 1a4e11ab..c548abdf 100644 --- a/bench/easylogging-bench.cpp +++ b/bench/easylogging-bench.cpp @@ -5,12 +5,12 @@ _INITIALIZE_EASYLOGGINGPP int main(int, char* []) { int howmany = 1000000; - + // Load configuration from file - el::Configurations conf("easyl.conf"); - el::Loggers::reconfigureLogger("default", conf); - - for(int i = 0 ; i < howmany; ++i) - LOG(INFO) << "easylog message #" << i << ": This is some text for your pleasure"; - return 0; + el::Configurations conf("easyl.conf"); + el::Loggers::reconfigureLogger("default", conf); + + for(int i = 0 ; i < howmany; ++i) + LOG(INFO) << "easylog message #" << i << ": This is some text for your pleasure"; + return 0; } diff --git a/bench/g2log-async.cpp b/bench/g2log-async.cpp index 4af00cb0..273ac0d5 100644 --- a/bench/g2log-async.cpp +++ b/bench/g2log-async.cpp @@ -14,44 +14,44 @@ int main(int argc, char* argv[]) { using namespace std::chrono; using clock=steady_clock; - int thread_count = 10; - - if(argc > 1) - thread_count = atoi(argv[1]); - int howmany = 1000000; + int thread_count = 10; - g2LogWorker g2log(argv[0], "logs"); - g2::initializeLogging(&g2log); + if(argc > 1) + thread_count = atoi(argv[1]); + int howmany = 1000000; + + g2LogWorker g2log(argv[0], "logs"); + g2::initializeLogging(&g2log); - std::atomic msg_counter {0}; - vector threads; + std::atomic msg_counter {0}; + vector threads; auto start = clock::now(); - for (int t = 0; t < thread_count; ++t) - { - threads.push_back(std::thread([&]() - { - while (true) - { - int counter = ++msg_counter; - if (counter > howmany) break; - LOG(INFO) << "g2log message #" << counter << ": This is some text for your pleasure"; - } - })); - } + for (int t = 0; t < thread_count; ++t) + { + threads.push_back(std::thread([&]() + { + while (true) + { + int counter = ++msg_counter; + if (counter > howmany) break; + LOG(INFO) << "g2log message #" << counter << ": This is some text for your pleasure"; + } + })); + } - for(auto &t:threads) - { - t.join(); - }; - + for(auto &t:threads) + { + t.join(); + }; + duration delta = clock::now() - start; float deltaf = delta.count(); - auto rate = howmany/deltaf; - - cout << "Total: " << howmany << std::endl; - cout << "Threads: " << thread_count << std::endl; - std::cout << "Delta = " << deltaf << " seconds" << std::endl; - std::cout << "Rate = " << rate << "/sec" << std::endl; + auto rate = howmany/deltaf; + + cout << "Total: " << howmany << std::endl; + cout << "Threads: " << thread_count << std::endl; + std::cout << "Delta = " << deltaf << " seconds" << std::endl; + std::cout << "Rate = " << rate << "/sec" << std::endl; } diff --git a/bench/glog-bench-mt.cpp b/bench/glog-bench-mt.cpp index 5418c085..06529bcd 100644 --- a/bench/glog-bench-mt.cpp +++ b/bench/glog-bench-mt.cpp @@ -9,37 +9,37 @@ using namespace std; int main(int argc, char* argv[]) { - int thread_count = 10; - if(argc > 1) - thread_count = atoi(argv[1]); + int thread_count = 10; + if(argc > 1) + thread_count = atoi(argv[1]); - int howmany = 1000000; + int howmany = 1000000; - FLAGS_logtostderr = 0; - FLAGS_log_dir = "logs"; - google::InitGoogleLogging(argv[0]); + FLAGS_logtostderr = 0; + FLAGS_log_dir = "logs"; + google::InitGoogleLogging(argv[0]); - std::atomic msg_counter {0}; - vector threads; + std::atomic msg_counter {0}; + vector threads; - for (int t = 0; t < thread_count; ++t) - { - threads.push_back(std::thread([&]() - { - while (true) - { - int counter = ++msg_counter; - if (counter > howmany) break; - LOG(INFO) << "glog message #" << counter << ": This is some text for your pleasure"; - } - })); - } + for (int t = 0; t < thread_count; ++t) + { + threads.push_back(std::thread([&]() + { + while (true) + { + int counter = ++msg_counter; + if (counter > howmany) break; + LOG(INFO) << "glog message #" << counter << ": This is some text for your pleasure"; + } + })); + } - for(auto &t:threads) - { - t.join(); - }; + for(auto &t:threads) + { + t.join(); + }; - return 0; + return 0; } diff --git a/bench/glog-bench.cpp b/bench/glog-bench.cpp index 837fce53..c0e86526 100644 --- a/bench/glog-bench.cpp +++ b/bench/glog-bench.cpp @@ -4,14 +4,14 @@ int main(int, char* argv[]) { - int howmany = 1000000; + int howmany = 1000000; - FLAGS_logtostderr = 0; - FLAGS_log_dir = "logs"; - google::InitGoogleLogging(argv[0]); - for(int i = 0 ; i < howmany; ++i) - LOG(INFO) << "glog message # " << i << ": This is some text for your pleasure"; + FLAGS_logtostderr = 0; + FLAGS_log_dir = "logs"; + google::InitGoogleLogging(argv[0]); + for(int i = 0 ; i < howmany; ++i) + LOG(INFO) << "glog message # " << i << ": This is some text for your pleasure"; - return 0; + return 0; } diff --git a/bench/spdlog-async.cpp b/bench/spdlog-async.cpp index aca38ce4..38e0c957 100644 --- a/bench/spdlog-async.cpp +++ b/bench/spdlog-async.cpp @@ -11,48 +11,48 @@ using namespace std; int main(int argc, char* argv[]) { - + using namespace std::chrono; using clock=steady_clock; namespace spd = spdlog; - - int thread_count = 10; - if(argc > 1) - thread_count = atoi(argv[1]); - int howmany = 1000000; - - spd::set_async_mode(1048576); - auto logger = spdlog::create("file_logger", "logs/spd-bench-async.txt", false); - logger->set_pattern("[%Y-%b-%d %T.%e]: %v"); + + int thread_count = 10; + if(argc > 1) + thread_count = atoi(argv[1]); + int howmany = 1000000; + + spd::set_async_mode(1048576); + auto logger = spdlog::create("file_logger", "logs/spd-bench-async.txt", false); + logger->set_pattern("[%Y-%b-%d %T.%e]: %v"); - std::atomic msg_counter {0}; - vector threads; + std::atomic msg_counter {0}; + vector threads; auto start = clock::now(); - for (int t = 0; t < thread_count; ++t) - { - threads.push_back(std::thread([&]() - { - while (true) - { - int counter = ++msg_counter; - if (counter > howmany) break; - logger->info() << "spdlog message #" << counter << ": This is some text for your pleasure"; - } - })); - } + for (int t = 0; t < thread_count; ++t) + { + threads.push_back(std::thread([&]() + { + while (true) + { + int counter = ++msg_counter; + if (counter > howmany) break; + logger->info() << "spdlog message #" << counter << ": This is some text for your pleasure"; + } + })); + } + + for(auto &t:threads) + { + t.join(); + }; - for(auto &t:threads) - { - t.join(); - }; - duration delta = clock::now() - start; float deltaf = delta.count(); - auto rate = howmany/deltaf; - - cout << "Total: " << howmany << std::endl; - cout << "Threads: " << thread_count << std::endl; - std::cout << "Delta = " << deltaf << " seconds" << std::endl; - std::cout << "Rate = " << rate << "/sec" << std::endl; + auto rate = howmany/deltaf; + + cout << "Total: " << howmany << std::endl; + cout << "Threads: " << thread_count << std::endl; + std::cout << "Delta = " << deltaf << " seconds" << std::endl; + std::cout << "Rate = " << rate << "/sec" << std::endl; } diff --git a/bench/spdlog-bench-mt.cpp b/bench/spdlog-bench-mt.cpp index d69a01e5..68dc81aa 100644 --- a/bench/spdlog-bench-mt.cpp +++ b/bench/spdlog-bench-mt.cpp @@ -10,41 +10,41 @@ using namespace std; int main(int argc, char* argv[]) { - int thread_count = 10; - if(argc > 1) - thread_count = atoi(argv[1]); + int thread_count = 10; + if(argc > 1) + thread_count = atoi(argv[1]); - int howmany = 1000000; + int howmany = 1000000; - namespace spd = spdlog; + namespace spd = spdlog; - auto logger = spdlog::create("file_logger", "logs/spd-bench-mt.txt", false); + auto logger = spdlog::create("file_logger", "logs/spd-bench-mt.txt", false); - logger->set_pattern("[%Y-%b-%d %T.%e]: %v"); + logger->set_pattern("[%Y-%b-%d %T.%e]: %v"); - std::atomic msg_counter {0}; - vector threads; + std::atomic msg_counter {0}; + vector threads; - for (int t = 0; t < thread_count; ++t) - { - threads.push_back(std::thread([&]() - { - while (true) - { - int counter = ++msg_counter; - if (counter > howmany) break; - logger->info() << "spdlog message #" << counter << ": This is some text for your pleasure"; - } - })); - } + for (int t = 0; t < thread_count; ++t) + { + threads.push_back(std::thread([&]() + { + while (true) + { + int counter = ++msg_counter; + if (counter > howmany) break; + logger->info() << "spdlog message #" << counter << ": This is some text for your pleasure"; + } + })); + } - for(auto &t:threads) - { - t.join(); - }; + for(auto &t:threads) + { + t.join(); + }; - return 0; + return 0; } diff --git a/bench/spdlog-bench.cpp b/bench/spdlog-bench.cpp index e0b41f35..e9a5d386 100644 --- a/bench/spdlog-bench.cpp +++ b/bench/spdlog-bench.cpp @@ -4,13 +4,13 @@ int main(int, char* []) { - int howmany = 1000000; - namespace spd = spdlog; - ///Create a file rotating logger with 5mb size max and 3 rotated files - auto logger = spdlog::create("file_logger", "logs/spd-bench-st.txt", false); + int howmany = 1000000; + namespace spd = spdlog; + ///Create a file rotating logger with 5mb size max and 3 rotated files + auto logger = spdlog::create("file_logger", "logs/spd-bench-st.txt", false); - logger->set_pattern("[%Y-%b-%d %T.%e]: %v"); - for(int i = 0 ; i < howmany; ++i) - logger->info() << "spdlog message #" << i << ": This is some text for your pleasure"; - return 0; + logger->set_pattern("[%Y-%b-%d %T.%e]: %v"); + for(int i = 0 ; i < howmany; ++i) + logger->info() << "spdlog message #" << i << ": This is some text for your pleasure"; + return 0; } diff --git a/example/bench.cpp b/example/bench.cpp index a9b9a9bf..72e95c63 100644 --- a/example/bench.cpp +++ b/example/bench.cpp @@ -50,110 +50,110 @@ void bench_mt(int howmany, std::shared_ptr log, int thread_count int main(int argc, char* argv[]) { - int howmany = 1048576; - int threads = 10; - bool auto_flush = false; - int file_size = 30 * 1024 * 1024; - int rotating_files = 5; + int howmany = 1048576; + int threads = 10; + bool auto_flush = false; + int file_size = 30 * 1024 * 1024; + int rotating_files = 5; - try - { + try + { - if(argc > 1) - howmany = atoi(argv[1]); - if (argc > 2) - threads = atoi(argv[2]); - - - cout << "*******************************************************************************\n"; - cout << "Single thread, " << format(howmany) << " iterations, auto flush=" << auto_flush << endl; - cout << "*******************************************************************************\n"; - - auto rotating_st = spdlog::rotating_logger_st("rotating_st", "logs/rotating_st", file_size, rotating_files, auto_flush); - bench(howmany, rotating_st); - auto daily_st = spdlog::daily_logger_st("daily_st", "logs/daily_st", auto_flush); - bench(howmany, daily_st); - bench(howmany, spdlog::create("null_st")); - - cout << "\n*******************************************************************************\n"; - cout << threads << " threads sharing same logger, " << format(howmany) << " iterations, auto_flush=" << auto_flush << endl; - cout << "*******************************************************************************\n"; - - auto rotating_mt = spdlog::rotating_logger_mt("rotating_mt", "logs/rotating_mt", file_size, rotating_files, auto_flush); - bench_mt(howmany, rotating_mt, threads); + if(argc > 1) + howmany = atoi(argv[1]); + if (argc > 2) + threads = atoi(argv[2]); - auto daily_mt = spdlog::daily_logger_mt("daily_mt", "logs/daily_mt", auto_flush); - bench_mt(howmany, daily_mt, threads); - bench(howmany, spdlog::create("null_mt")); - - cout << "\n*******************************************************************************\n"; - cout << "async logging.. " << threads << " threads sharing same logger, " << format(howmany) << " iterations, auto_flush=" << auto_flush << endl; - cout << "*******************************************************************************\n"; + cout << "*******************************************************************************\n"; + cout << "Single thread, " << format(howmany) << " iterations, auto flush=" << auto_flush << endl; + cout << "*******************************************************************************\n"; + + auto rotating_st = spdlog::rotating_logger_st("rotating_st", "logs/rotating_st", file_size, rotating_files, auto_flush); + bench(howmany, rotating_st); + auto daily_st = spdlog::daily_logger_st("daily_st", "logs/daily_st", auto_flush); + bench(howmany, daily_st); + bench(howmany, spdlog::create("null_st")); + + cout << "\n*******************************************************************************\n"; + cout << threads << " threads sharing same logger, " << format(howmany) << " iterations, auto_flush=" << auto_flush << endl; + cout << "*******************************************************************************\n"; + + auto rotating_mt = spdlog::rotating_logger_mt("rotating_mt", "logs/rotating_mt", file_size, rotating_files, auto_flush); + bench_mt(howmany, rotating_mt, threads); - spdlog::set_async_mode(howmany); + auto daily_mt = spdlog::daily_logger_mt("daily_mt", "logs/daily_mt", auto_flush); + bench_mt(howmany, daily_mt, threads); + bench(howmany, spdlog::create("null_mt")); - for(int i = 0; i < 3; ++i) - { - auto as = spdlog::daily_logger_st("as", "logs/daily_async", auto_flush); - bench_mt(howmany, as, threads); - spdlog::drop("as"); - } - } - catch (std::exception &ex) - { - std::cerr << "Error: " << ex.what() << std::endl; - perror("Last error"); - } - return 0; + cout << "\n*******************************************************************************\n"; + cout << "async logging.. " << threads << " threads sharing same logger, " << format(howmany) << " iterations, auto_flush=" << auto_flush << endl; + cout << "*******************************************************************************\n"; + + + spdlog::set_async_mode(howmany); + + for(int i = 0; i < 3; ++i) + { + auto as = spdlog::daily_logger_st("as", "logs/daily_async", auto_flush); + bench_mt(howmany, as, threads); + spdlog::drop("as"); + } + } + catch (std::exception &ex) + { + std::cerr << "Error: " << ex.what() << std::endl; + perror("Last error"); + } + return 0; } void bench(int howmany, std::shared_ptr log) { - cout << log->name() << "...\t\t" << flush; - auto start = system_clock::now(); - for (auto i = 0; i < howmany; ++i) - { - log->info("Hello logger: msg number {}", i); - } + cout << log->name() << "...\t\t" << flush; + auto start = system_clock::now(); + for (auto i = 0; i < howmany; ++i) + { + log->info("Hello logger: msg number {}", i); + } - auto delta = system_clock::now() - start; - auto delta_d = duration_cast> (delta).count(); - cout << format(int(howmany / delta_d)) << "/sec" << endl; + auto delta = system_clock::now() - start; + auto delta_d = duration_cast> (delta).count(); + cout << format(int(howmany / delta_d)) << "/sec" << endl; } void bench_mt(int howmany, std::shared_ptr log, int thread_count) { - cout << log->name() << "...\t\t" << flush; - std::atomic msg_counter {0}; - vector threads; - auto start = system_clock::now(); - for (int t = 0; t < thread_count; ++t) - { - threads.push_back(std::thread([&]() - { - for(;;) - { - int counter = ++msg_counter; - if (counter > howmany) break; - log->info("Hello logger: msg number {}", counter); - } - })); - } + cout << log->name() << "...\t\t" << flush; + std::atomic msg_counter {0}; + vector threads; + auto start = system_clock::now(); + for (int t = 0; t < thread_count; ++t) + { + threads.push_back(std::thread([&]() + { + for(;;) + { + int counter = ++msg_counter; + if (counter > howmany) break; + log->info("Hello logger: msg number {}", counter); + } + })); + } - for(auto &t:threads) - { - t.join(); - }; + for(auto &t:threads) + { + t.join(); + }; - auto delta = system_clock::now() - start; - auto delta_d = duration_cast> (delta).count(); - cout << format(int(howmany / delta_d)) << "/sec" << endl; + auto delta = system_clock::now() - start; + auto delta_d = duration_cast> (delta).count(); + cout << format(int(howmany / delta_d)) << "/sec" << endl; } diff --git a/example/example.cpp b/example/example.cpp index 26d2e72b..5454bc5a 100644 --- a/example/example.cpp +++ b/example/example.cpp @@ -30,61 +30,61 @@ int main(int, char* []) { - namespace spd = spdlog; - try - { - // Set log level to all loggers to debug and above - spd::set_level(spd::level::debug); + namespace spd = spdlog; + try + { + // Set log level to all loggers to debug and above + spd::set_level(spd::level::debug); - // Create console, multithreaded logger - auto console = spd::stdout_logger_mt("console"); - console->info("Welcome to spdlog!") ; - console->info("An info message example {}..", 1); - console->info() << "Streams are supported too " << 1; + // Create console, multithreaded logger + auto console = spd::stdout_logger_mt("console"); + console->info("Welcome to spdlog!") ; + console->info("An info message example {}..", 1); + console->info() << "Streams are supported too " << 1; - console->info("Easy padding in numbers like {:08d}", 12); - console->info("Support for int: {0:d}; hex: {0:x}; oct: {0:o}; bin: {0:b}", 42); - console->info("Support for floats {:03.2f}", 1.23456); - console->info("Positional args are {1} {0}..", "too", "supported"); + console->info("Easy padding in numbers like {:08d}", 12); + console->info("Support for int: {0:d}; hex: {0:x}; oct: {0:o}; bin: {0:b}", 42); + console->info("Support for floats {:03.2f}", 1.23456); + console->info("Positional args are {1} {0}..", "too", "supported"); - console->info("{:<30}", "left aligned"); - console->info("{:>30}", "right aligned"); - console->info("{:^30}", "centered"); - - // Create a file rotating logger with 5mb size max and 3 rotated files - auto file_logger = spd::rotating_logger_mt("file_logger", "logs/mylogfile", 1048576 * 5, 3); - file_logger->set_level(spd::level::info); - for(int i = 0; i < 10; ++i) - file_logger->info("{} * {} equals {:>10}", i, i, i*i); + console->info("{:<30}", "left aligned"); + console->info("{:>30}", "right aligned"); + console->info("{:^30}", "centered"); - // Customize msg format for all messages - spd::set_pattern("*** [%H:%M:%S %z] [thread %t] %v ***"); - file_logger->info("This is another message with custom format"); + // Create a file rotating logger with 5mb size max and 3 rotated files + auto file_logger = spd::rotating_logger_mt("file_logger", "logs/mylogfile", 1048576 * 5, 3); + file_logger->set_level(spd::level::info); + for(int i = 0; i < 10; ++i) + file_logger->info("{} * {} equals {:>10}", i, i, i*i); - spd::get("console")->info("loggers can be retrieved from a global registry using the spdlog::get(logger_name) function"); + // Customize msg format for all messages + spd::set_pattern("*** [%H:%M:%S %z] [thread %t] %v ***"); + file_logger->info("This is another message with custom format"); - SPDLOG_TRACE(console, "Enabled only #ifdef SPDLOG_TRACE_ON..{} ,{}", 1, 3.23); - SPDLOG_DEBUG(console, "Enabled only #ifdef SPDLOG_DEBUG_ON.. {} ,{}", 1, 3.23); + spd::get("console")->info("loggers can be retrieved from a global registry using the spdlog::get(logger_name) function"); - // - // Asynchronous logging is very fast.. - // Just call spdlog::set_async_mode(q_size) and all created loggers from now on will be asynchronous.. - // - size_t q_size = 1048576; //queue size must be power of 2 - spdlog::set_async_mode(q_size); - auto async_file= spd::daily_logger_st("async_file_logger", "logs/async_log.txt"); - async_file->info() << "This is async log.." << "Should be very fast!"; - - // syslog example. linux only.. - #ifdef __linux__ - std::string ident = "spdlog-example"; - auto syslog_logger = spd::syslog_logger("syslog", ident, LOG_PID); - syslog_logger->warn("This is warning that will end up in syslog. This is Linux only!"); - #endif + SPDLOG_TRACE(console, "Enabled only #ifdef SPDLOG_TRACE_ON..{} ,{}", 1, 3.23); + SPDLOG_DEBUG(console, "Enabled only #ifdef SPDLOG_DEBUG_ON.. {} ,{}", 1, 3.23); - } - catch (const spd::spdlog_ex& ex) - { - std::cout << "Log failed: " << ex.what() << std::endl; - } + // + // Asynchronous logging is very fast.. + // Just call spdlog::set_async_mode(q_size) and all created loggers from now on will be asynchronous.. + // + size_t q_size = 1048576; //queue size must be power of 2 + spdlog::set_async_mode(q_size); + auto async_file= spd::daily_logger_st("async_file_logger", "logs/async_log.txt"); + async_file->info() << "This is async log.." << "Should be very fast!"; + + // syslog example. linux only.. +#ifdef __linux__ + std::string ident = "spdlog-example"; + auto syslog_logger = spd::syslog_logger("syslog", ident, LOG_PID); + syslog_logger->warn("This is warning that will end up in syslog. This is Linux only!"); +#endif + + } + catch (const spd::spdlog_ex& ex) + { + std::cout << "Log failed: " << ex.what() << std::endl; + } } diff --git a/example/utils.h b/example/utils.h index 95dd9257..b890ac39 100644 --- a/example/utils.h +++ b/example/utils.h @@ -34,21 +34,21 @@ namespace utils template inline std::string format(const T& value) { - static std::locale loc(""); - std::stringstream ss; - ss.imbue(loc); - ss << value; - return ss.str(); + static std::locale loc(""); + std::stringstream ss; + ss.imbue(loc); + ss << value; + return ss.str(); } template<> inline std::string format(const double & value) { - static std::locale loc(""); - std::stringstream ss; - ss.imbue(loc); - ss << std::fixed << std::setprecision(1) << value; - return ss.str(); + static std::locale loc(""); + std::stringstream ss; + ss.imbue(loc); + ss << std::fixed << std::setprecision(1) << value; + return ss.str(); } } diff --git a/include/spdlog/async_logger.h b/include/spdlog/async_logger.h index 518e61cf..9ad6818d 100644 --- a/include/spdlog/async_logger.h +++ b/include/spdlog/async_logger.h @@ -50,20 +50,20 @@ class async_log_helper; class async_logger :public logger { public: - template - async_logger(const std::string& name, const It& begin, const It& end, size_t queue_size); - async_logger(const std::string& logger_name, sinks_init_list sinks, size_t queue_size); - async_logger(const std::string& logger_name, sink_ptr single_sink, size_t queue_size); + template + async_logger(const std::string& name, const It& begin, const It& end, size_t queue_size); + async_logger(const std::string& logger_name, sinks_init_list sinks, size_t queue_size); + async_logger(const std::string& logger_name, sink_ptr single_sink, size_t queue_size); protected: - void _log_msg(details::log_msg& msg) override; - void _set_formatter(spdlog::formatter_ptr msg_formatter) override; - void _set_pattern(const std::string& pattern) override; - void _stop() override; + void _log_msg(details::log_msg& msg) override; + void _set_formatter(spdlog::formatter_ptr msg_formatter) override; + void _set_pattern(const std::string& pattern) override; + void _stop() override; private: - std::unique_ptr _async_log_helper; + std::unique_ptr _async_log_helper; }; } diff --git a/include/spdlog/common.h b/include/spdlog/common.h index 509a90e6..323f0c25 100644 --- a/include/spdlog/common.h +++ b/include/spdlog/common.h @@ -39,7 +39,8 @@ namespace spdlog class formatter; -namespace sinks { +namespace sinks +{ class sink; } @@ -70,7 +71,7 @@ static const char* level_names[] { "trace", "debug", "info", "notice", "warning" inline const char* to_str(spdlog::level::level_enum l) { - return level_names[l]; + return level_names[l]; } } //level @@ -80,13 +81,13 @@ inline const char* to_str(spdlog::level::level_enum l) class spdlog_ex : public std::exception { public: - spdlog_ex(const std::string& msg) :_msg(msg) {} - const char* what() const SPDLOG_NOEXCEPT override - { - return _msg.c_str(); - } + spdlog_ex(const std::string& msg) :_msg(msg) {} + const char* what() const SPDLOG_NOEXCEPT override + { + return _msg.c_str(); + } private: - std::string _msg; + std::string _msg; }; diff --git a/include/spdlog/details/async_log_helper.h b/include/spdlog/details/async_log_helper.h index 6b76879d..43133e3b 100644 --- a/include/spdlog/details/async_log_helper.h +++ b/include/spdlog/details/async_log_helper.h @@ -52,93 +52,93 @@ namespace details class async_log_helper { - // Async msg to move to/from the queue - // Movable only. should never be copied - struct async_msg - { - std::string logger_name; - level::level_enum level; - log_clock::time_point time; - std::string txt; + // Async msg to move to/from the queue + // Movable only. should never be copied + struct async_msg + { + std::string logger_name; + level::level_enum level; + log_clock::time_point time; + std::string txt; - async_msg() = default; - ~async_msg() = default; + async_msg() = default; + ~async_msg() = default; - async_msg(const async_msg&) = delete; - async_msg& operator=(async_msg& other) = delete; + async_msg(const async_msg&) = delete; + async_msg& operator=(async_msg& other) = delete; - async_msg(const details::log_msg& m) : - logger_name(m.logger_name), - level(m.level), - time(m.time), - txt(m.raw.data(), m.raw.size()) - {} + async_msg(const details::log_msg& m) : + logger_name(m.logger_name), + level(m.level), + time(m.time), + txt(m.raw.data(), m.raw.size()) + {} - async_msg(async_msg&& other) : - logger_name(std::move(other.logger_name)), - level(std::move(other.level)), - time(std::move(other.time)), - txt(std::move(other.txt)) - {} + async_msg(async_msg&& other) : + logger_name(std::move(other.logger_name)), + level(std::move(other.level)), + time(std::move(other.time)), + txt(std::move(other.txt)) + {} - async_msg& operator=(async_msg&& other) - { - logger_name = std::move(other.logger_name); - level = other.level; - time = std::move(other.time); - txt = std::move(other.txt); - return *this; - } + async_msg& operator=(async_msg&& other) + { + logger_name = std::move(other.logger_name); + level = other.level; + time = std::move(other.time); + txt = std::move(other.txt); + return *this; + } - void fill_log_msg(log_msg &msg) - { - msg.clear(); - msg.logger_name = logger_name; - msg.level = level; - msg.time = time; - msg.raw << txt; - } - }; + void fill_log_msg(log_msg &msg) + { + msg.clear(); + msg.logger_name = logger_name; + msg.level = level; + msg.time = time; + msg.raw << txt; + } + }; public: - using item_type = async_msg; - using q_type = details::mpmc_bounded_queue; + using item_type = async_msg; + using q_type = details::mpmc_bounded_queue; - using clock = std::chrono::steady_clock; + using clock = std::chrono::steady_clock; - async_log_helper(formatter_ptr formatter, const std::vector& sinks, size_t queue_size); - void log(const details::log_msg& msg); + async_log_helper(formatter_ptr formatter, const std::vector& sinks, size_t queue_size); + void log(const details::log_msg& msg); - //Stop logging and join the back thread - ~async_log_helper(); - void set_formatter(formatter_ptr); + //Stop logging and join the back thread + ~async_log_helper(); + void set_formatter(formatter_ptr); private: - formatter_ptr _formatter; - std::vector> _sinks; - q_type _q; - std::thread _worker_thread; + formatter_ptr _formatter; + std::vector> _sinks; + q_type _q; + std::thread _worker_thread; - // last exception thrown from the worker thread - std::shared_ptr _last_workerthread_ex; + // last exception thrown from the worker thread + std::shared_ptr _last_workerthread_ex; - // throw last worker thread exception or if worker thread is not active - void throw_if_bad_worker(); + // throw last worker thread exception or if worker thread is not active + void throw_if_bad_worker(); - // worker thread main loop - void worker_loop(); + // worker thread main loop + void worker_loop(); - //pop next message from the queue and process it - //return true if a message was available (queue was not empty), will set the last_pop to the pop time - bool process_next_msg(clock::time_point& last_pop); + //pop next message from the queue and process it + //return true if a message was available (queue was not empty), will set the last_pop to the pop time + bool process_next_msg(clock::time_point& last_pop); - // guess how much to sleep if queue is empty/full using last succesful op time as hint - static void sleep_or_yield(const clock::time_point& last_op_time); + // guess how much to sleep if queue is empty/full using last succesful op time as hint + static void sleep_or_yield(const clock::time_point& last_op_time); }; } @@ -148,10 +148,10 @@ private: // async_sink class implementation /////////////////////////////////////////////////////////////////////////////// inline spdlog::details::async_log_helper::async_log_helper(formatter_ptr formatter, const std::vector& sinks, size_t queue_size): - _formatter(formatter), - _sinks(sinks), - _q(queue_size), - _worker_thread(&async_log_helper::worker_loop, this) + _formatter(formatter), + _sinks(sinks), + _q(queue_size), + _worker_thread(&async_log_helper::worker_loop, this) {} // Send to the worker thread termination message(level=off) @@ -159,48 +159,48 @@ inline spdlog::details::async_log_helper::async_log_helper(formatter_ptr formatt inline spdlog::details::async_log_helper::~async_log_helper() { - try - { - log(log_msg(level::off)); - _worker_thread.join(); - } - catch (...) //Dont crash if thread not joinable - {} + try + { + log(log_msg(level::off)); + _worker_thread.join(); + } + catch (...) //Dont crash if thread not joinable + {} } //Try to push and block until succeeded inline void spdlog::details::async_log_helper::log(const details::log_msg& msg) { - throw_if_bad_worker(); - async_msg new_msg(msg); - if (!_q.enqueue(std::move(new_msg))) - { - auto last_op_time = clock::now(); - do - { - sleep_or_yield(last_op_time); - } - while (!_q.enqueue(std::move(new_msg))); - } + throw_if_bad_worker(); + async_msg new_msg(msg); + if (!_q.enqueue(std::move(new_msg))) + { + auto last_op_time = clock::now(); + do + { + sleep_or_yield(last_op_time); + } + while (!_q.enqueue(std::move(new_msg))); + } } inline void spdlog::details::async_log_helper::worker_loop() { - try + try { - clock::time_point last_pop = clock::now(); - while(process_next_msg(last_pop)); - } + clock::time_point last_pop = clock::now(); + while(process_next_msg(last_pop)); + } catch (const std::exception& ex) - { - _last_workerthread_ex = std::make_shared(std::string("async_logger worker thread exception: ") + ex.what()); - } - catch (...) - { - _last_workerthread_ex = std::make_shared("async_logger worker thread exception"); - } + { + _last_workerthread_ex = std::make_shared(std::string("async_logger worker thread exception: ") + ex.what()); + } + catch (...) + { + _last_workerthread_ex = std::make_shared("async_logger worker thread exception"); + } } // Process next message in the queue @@ -208,66 +208,66 @@ inline void spdlog::details::async_log_helper::worker_loop() inline bool spdlog::details::async_log_helper::process_next_msg(clock::time_point& last_pop) { - async_msg incoming_async_msg; - log_msg incoming_log_msg; + async_msg incoming_async_msg; + log_msg incoming_log_msg; - if (_q.dequeue(incoming_async_msg)) - { + if (_q.dequeue(incoming_async_msg)) + { last_pop = clock::now(); - - if(incoming_async_msg.level == level::off) + + if(incoming_async_msg.level == level::off) return false; - incoming_async_msg.fill_log_msg(incoming_log_msg); - _formatter->format(incoming_log_msg); - for (auto &s : _sinks) - s->log(incoming_log_msg); - } - else //empty queue - { - sleep_or_yield(last_pop); - } - return true; + incoming_async_msg.fill_log_msg(incoming_log_msg); + _formatter->format(incoming_log_msg); + for (auto &s : _sinks) + s->log(incoming_log_msg); + } + else //empty queue + { + sleep_or_yield(last_pop); + } + return true; } inline void spdlog::details::async_log_helper::set_formatter(formatter_ptr msg_formatter) { - _formatter = msg_formatter; + _formatter = msg_formatter; } // Sleep,yield or return immediatly using the time passed since last message as a hint inline void spdlog::details::async_log_helper::sleep_or_yield(const clock::time_point& last_op_time) { - using std::chrono::milliseconds; - using namespace std::this_thread; + using std::chrono::milliseconds; + using namespace std::this_thread; - auto time_since_op = clock::now() - last_op_time; + auto time_since_op = clock::now() - last_op_time; - //spin upto 1 ms - if (time_since_op <= milliseconds(1)) - return; + //spin upto 1 ms + if (time_since_op <= milliseconds(1)) + return; - // yield upto 10ms - if (time_since_op <= milliseconds(10)) - return yield(); + // yield upto 10ms + if (time_since_op <= milliseconds(10)) + return yield(); - // sleep for half of duration since last op - if (time_since_op <= milliseconds(100)) - return sleep_for(time_since_op / 2); + // sleep for half of duration since last op + if (time_since_op <= milliseconds(100)) + return sleep_for(time_since_op / 2); - return sleep_for(milliseconds(100)); + return sleep_for(milliseconds(100)); } //throw if the worker thread threw an exception or not active inline void spdlog::details::async_log_helper::throw_if_bad_worker() { - if (_last_workerthread_ex) - { - auto ex = std::move(_last_workerthread_ex); - throw *ex; - } + if (_last_workerthread_ex) + { + auto ex = std::move(_last_workerthread_ex); + throw *ex; + } } diff --git a/include/spdlog/details/async_logger_impl.h b/include/spdlog/details/async_logger_impl.h index cb9b1bc9..0cffe9eb 100644 --- a/include/spdlog/details/async_logger_impl.h +++ b/include/spdlog/details/async_logger_impl.h @@ -35,38 +35,38 @@ template inline spdlog::async_logger::async_logger(const std::string& logger_name, const It& begin, const It& end, size_t queue_size) : - logger(logger_name, begin, end), - _async_log_helper(new details::async_log_helper(_formatter, _sinks, queue_size)) + logger(logger_name, begin, end), + _async_log_helper(new details::async_log_helper(_formatter, _sinks, queue_size)) { } inline spdlog::async_logger::async_logger(const std::string& logger_name, sinks_init_list sinks, size_t queue_size) : - async_logger(logger_name, sinks.begin(), sinks.end(), queue_size) {} + async_logger(logger_name, sinks.begin(), sinks.end(), queue_size) {} inline spdlog::async_logger::async_logger(const std::string& logger_name, sink_ptr single_sink, size_t queue_size) : - async_logger(logger_name, { single_sink }, queue_size) {} + async_logger(logger_name, { single_sink }, queue_size) {} inline void spdlog::async_logger::_set_formatter(spdlog::formatter_ptr msg_formatter) { - _formatter = msg_formatter; - _async_log_helper->set_formatter(_formatter); + _formatter = msg_formatter; + _async_log_helper->set_formatter(_formatter); } inline void spdlog::async_logger::_set_pattern(const std::string& pattern) { - _formatter = std::make_shared(pattern); - _async_log_helper->set_formatter(_formatter); + _formatter = std::make_shared(pattern); + _async_log_helper->set_formatter(_formatter); } inline void spdlog::async_logger::_stop() { - set_level(level::off); + set_level(level::off); } inline void spdlog::async_logger::_log_msg(details::log_msg& msg) { - _async_log_helper->log(msg); + _async_log_helper->log(msg); } diff --git a/include/spdlog/details/file_helper.h b/include/spdlog/details/file_helper.h index fbc48e70..8adf38c1 100644 --- a/include/spdlog/details/file_helper.h +++ b/include/spdlog/details/file_helper.h @@ -45,93 +45,93 @@ namespace details class file_helper { public: - const int open_tries = 5; - const int open_interval = 10; + const int open_tries = 5; + const int open_interval = 10; - explicit file_helper(bool auto_flush): - _fd(nullptr), - _auto_flush(auto_flush) - {} + explicit file_helper(bool auto_flush): + _fd(nullptr), + _auto_flush(auto_flush) + {} - file_helper(const file_helper&) = delete; - file_helper& operator=(const file_helper&) = delete; + file_helper(const file_helper&) = delete; + file_helper& operator=(const file_helper&) = delete; - ~file_helper() - { - close(); - } + ~file_helper() + { + close(); + } - void open(const std::string& fname, bool truncate=false) - { + void open(const std::string& fname, bool truncate=false) + { - close(); + close(); const char* mode = truncate ? "wb" : "ab"; - _filename = fname; - for (int tries = 0; tries < open_tries; ++tries) - { - if(!os::fopen_s(&_fd, fname, mode)) - return; + _filename = fname; + for (int tries = 0; tries < open_tries; ++tries) + { + if(!os::fopen_s(&_fd, fname, mode)) + return; - std::this_thread::sleep_for(std::chrono::milliseconds(open_interval)); - } + std::this_thread::sleep_for(std::chrono::milliseconds(open_interval)); + } - throw spdlog_ex("Failed opening file " + fname + " for writing"); - } + throw spdlog_ex("Failed opening file " + fname + " for writing"); + } - void reopen(bool truncate) - { - if(_filename.empty()) - throw spdlog_ex("Failed re opening file - was not opened before"); - open(_filename, truncate); + void reopen(bool truncate) + { + if(_filename.empty()) + throw spdlog_ex("Failed re opening file - was not opened before"); + open(_filename, truncate); - } + } - void close() - { - if (_fd) - { - std::fclose(_fd); - _fd = nullptr; - } - } + void close() + { + if (_fd) + { + std::fclose(_fd); + _fd = nullptr; + } + } - void write(const log_msg& msg) - { + void write(const log_msg& msg) + { - size_t size = msg.formatted.size(); - auto data = msg.formatted.data(); - if(std::fwrite(data, 1, size, _fd) != size) - throw spdlog_ex("Failed writing to file " + _filename); + size_t size = msg.formatted.size(); + auto data = msg.formatted.data(); + if(std::fwrite(data, 1, size, _fd) != size) + throw spdlog_ex("Failed writing to file " + _filename); - if(_auto_flush) - std::fflush(_fd); + if(_auto_flush) + std::fflush(_fd); - } + } - const std::string& filename() const - { - return _filename; - } + const std::string& filename() const + { + return _filename; + } - static bool file_exists(const std::string& name) - { - FILE* file; - if (!os::fopen_s(&file, name.c_str(), "r")) - { - fclose(file); - return true; - } - else - { - return false; - } - } + static bool file_exists(const std::string& name) + { + FILE* file; + if (!os::fopen_s(&file, name.c_str(), "r")) + { + fclose(file); + return true; + } + else + { + return false; + } + } private: - FILE* _fd; - std::string _filename; - bool _auto_flush; + FILE* _fd; + std::string _filename; + bool _auto_flush; }; diff --git a/include/spdlog/details/format.h b/include/spdlog/details/format.h index 3934f812..99f41838 100644 --- a/include/spdlog/details/format.h +++ b/include/spdlog/details/format.h @@ -172,60 +172,60 @@ template class BasicStringRef { private: - const Char *data_; - std::size_t size_; + const Char *data_; + std::size_t size_; public: - /** - Constructs a string reference object from a C string and a size. - */ - BasicStringRef(const Char *s, std::size_t size) : data_(s), size_(size) {} + /** + Constructs a string reference object from a C string and a size. + */ + BasicStringRef(const Char *s, std::size_t size) : data_(s), size_(size) {} - /** - Constructs a string reference object from a C string computing - the size with ``std::char_traits::length``. - */ - BasicStringRef(const Char *s) - : data_(s), size_(std::char_traits::length(s)) {} + /** + Constructs a string reference object from a C string computing + the size with ``std::char_traits::length``. + */ + BasicStringRef(const Char *s) + : data_(s), size_(std::char_traits::length(s)) {} - /** - Constructs a string reference from an `std::string` object. - */ - BasicStringRef(const std::basic_string &s) - : data_(s.c_str()), size_(s.size()) {} + /** + Constructs a string reference from an `std::string` object. + */ + BasicStringRef(const std::basic_string &s) + : data_(s.c_str()), size_(s.size()) {} - /** - Converts a string reference to an `std::string` object. - */ - operator std::basic_string() const - { - return std::basic_string(data_, size()); - } + /** + Converts a string reference to an `std::string` object. + */ + operator std::basic_string() const + { + return std::basic_string(data_, size()); + } - /** - Returns the pointer to a C string. - */ - const Char *c_str() const - { - return data_; - } + /** + Returns the pointer to a C string. + */ + const Char *c_str() const + { + return data_; + } - /** - Returns the string size. - */ - std::size_t size() const - { - return size_; - } + /** + Returns the string size. + */ + std::size_t size() const + { + return size_; + } - friend bool operator==(BasicStringRef lhs, BasicStringRef rhs) - { - return lhs.data_ == rhs.data_; - } - friend bool operator!=(BasicStringRef lhs, BasicStringRef rhs) - { - return lhs.data_ != rhs.data_; - } + friend bool operator==(BasicStringRef lhs, BasicStringRef rhs) + { + return lhs.data_ == rhs.data_; + } + friend bool operator!=(BasicStringRef lhs, BasicStringRef rhs) + { + return lhs.data_ != rhs.data_; + } }; typedef BasicStringRef StringRef; @@ -237,8 +237,8 @@ A formatting error such as invalid format string. class FormatError : public std::runtime_error { public: - explicit FormatError(StringRef message) - : std::runtime_error(message.c_str()) {} + explicit FormatError(StringRef message) + : std::runtime_error(message.c_str()) {} }; namespace internal @@ -253,13 +253,13 @@ enum { INLINE_BUFFER_SIZE = 500 }; template inline stdext::checked_array_iterator make_ptr(T *ptr, std::size_t size) { - return stdext::checked_array_iterator(ptr, size); + return stdext::checked_array_iterator(ptr, size); } #else template inline T *make_ptr(T *ptr, std::size_t) { - return ptr; + return ptr; } #endif @@ -268,81 +268,81 @@ template class Buffer { private: - FMT_DISALLOW_COPY_AND_ASSIGN(Buffer); + FMT_DISALLOW_COPY_AND_ASSIGN(Buffer); protected: - T *ptr_; - std::size_t size_; - std::size_t capacity_; + T *ptr_; + std::size_t size_; + std::size_t capacity_; - Buffer(T *ptr = 0, std::size_t capacity = 0) - : ptr_(ptr), size_(0), capacity_(capacity) {} + Buffer(T *ptr = 0, std::size_t capacity = 0) + : ptr_(ptr), size_(0), capacity_(capacity) {} - virtual void grow(std::size_t size) = 0; + virtual void grow(std::size_t size) = 0; public: - virtual ~Buffer() {} + virtual ~Buffer() {} - // Returns the size of this buffer. - std::size_t size() const - { - return size_; - } + // Returns the size of this buffer. + std::size_t size() const + { + return size_; + } - // Returns the capacity of this buffer. - std::size_t capacity() const - { - return capacity_; - } + // Returns the capacity of this buffer. + std::size_t capacity() const + { + return capacity_; + } - // Resizes the buffer. If T is a POD type new elements are not initialized. - void resize(std::size_t new_size) - { - if (new_size > capacity_) - grow(new_size); - size_ = new_size; - } + // Resizes the buffer. If T is a POD type new elements are not initialized. + void resize(std::size_t new_size) + { + if (new_size > capacity_) + grow(new_size); + size_ = new_size; + } - // Reserves space to store at least capacity elements. - void reserve(std::size_t capacity) - { - if (capacity > capacity_) - grow(capacity); - } + // Reserves space to store at least capacity elements. + void reserve(std::size_t capacity) + { + if (capacity > capacity_) + grow(capacity); + } - void clear() FMT_NOEXCEPT(true) - { - size_ = 0; - } + void clear() FMT_NOEXCEPT(true) + { + size_ = 0; + } - void push_back(const T &value) - { - if (size_ == capacity_) - grow(size_ + 1); - ptr_[size_++] = value; - } + void push_back(const T &value) + { + if (size_ == capacity_) + grow(size_ + 1); + ptr_[size_++] = value; + } - // Appends data to the end of the buffer. - void append(const T *begin, const T *end); + // Appends data to the end of the buffer. + void append(const T *begin, const T *end); - T &operator[](std::size_t index) - { - return ptr_[index]; - } - const T &operator[](std::size_t index) const - { - return ptr_[index]; - } + T &operator[](std::size_t index) + { + return ptr_[index]; + } + const T &operator[](std::size_t index) const + { + return ptr_[index]; + } }; template void Buffer::append(const T *begin, const T *end) { - std::ptrdiff_t num_elements = end - begin; - if (size_ + num_elements > capacity_) - grow(size_ + num_elements); - std::copy(begin, end, make_ptr(ptr_, capacity_) + size_); - size_ += num_elements; + std::ptrdiff_t num_elements = end - begin; + if (size_ + num_elements > capacity_) + grow(size_ + num_elements); + std::copy(begin, end, make_ptr(ptr_, capacity_) + size_); + size_ += num_elements; } // A memory buffer for POD types with the first SIZE elements stored in @@ -351,101 +351,101 @@ template > class MemoryBuffer : private Allocator, public Buffer { private: - T data_[SIZE]; + T data_[SIZE]; - // Free memory allocated by the buffer. - void free() - { - if (this->ptr_ != data_) this->deallocate(this->ptr_, this->capacity_); - } + // Free memory allocated by the buffer. + void free() + { + if (this->ptr_ != data_) this->deallocate(this->ptr_, this->capacity_); + } protected: - void grow(std::size_t size); + void grow(std::size_t size); public: - explicit MemoryBuffer(const Allocator &alloc = Allocator()) - : Allocator(alloc), Buffer(data_, SIZE) {} - ~MemoryBuffer() - { - free(); - } + explicit MemoryBuffer(const Allocator &alloc = Allocator()) + : Allocator(alloc), Buffer(data_, SIZE) {} + ~MemoryBuffer() + { + free(); + } #if FMT_USE_RVALUE_REFERENCES private: - // Move data from other to this buffer. - void move(MemoryBuffer &other) - { - Allocator &this_alloc = *this, &other_alloc = other; - this_alloc = std::move(other_alloc); - this->size_ = other.size_; - this->capacity_ = other.capacity_; - if (other.ptr_ == other.data_) - { - this->ptr_ = data_; - std::copy(other.data_, - other.data_ + this->size_, make_ptr(data_, this->capacity_)); - } - else - { - this->ptr_ = other.ptr_; - // Set pointer to the inline array so that delete is not called - // when freeing. - other.ptr_ = other.data_; - } - } + // Move data from other to this buffer. + void move(MemoryBuffer &other) + { + Allocator &this_alloc = *this, &other_alloc = other; + this_alloc = std::move(other_alloc); + this->size_ = other.size_; + this->capacity_ = other.capacity_; + if (other.ptr_ == other.data_) + { + this->ptr_ = data_; + std::copy(other.data_, + other.data_ + this->size_, make_ptr(data_, this->capacity_)); + } + else + { + this->ptr_ = other.ptr_; + // Set pointer to the inline array so that delete is not called + // when freeing. + other.ptr_ = other.data_; + } + } public: - MemoryBuffer(MemoryBuffer &&other) - { - move(other); - } + MemoryBuffer(MemoryBuffer &&other) + { + move(other); + } - MemoryBuffer &operator=(MemoryBuffer &&other) - { - assert(this != &other); - free(); - move(other); - return *this; - } + MemoryBuffer &operator=(MemoryBuffer &&other) + { + assert(this != &other); + free(); + move(other); + return *this; + } #endif - // Returns a copy of the allocator associated with this buffer. - Allocator get_allocator() const - { - return *this; - } + // Returns a copy of the allocator associated with this buffer. + Allocator get_allocator() const + { + return *this; + } }; template void MemoryBuffer::grow(std::size_t size) { - std::size_t new_capacity = - (std::max)(size, this->capacity_ + this->capacity_ / 2); - T *new_ptr = this->allocate(new_capacity); - // The following code doesn't throw, so the raw pointer above doesn't leak. - std::copy(this->ptr_, - this->ptr_ + this->size_, make_ptr(new_ptr, new_capacity)); - std::size_t old_capacity = this->capacity_; - T *old_ptr = this->ptr_; - this->capacity_ = new_capacity; - this->ptr_ = new_ptr; - // deallocate may throw (at least in principle), but it doesn't matter since - // the buffer already uses the new storage and will deallocate it in case - // of exception. - if (old_ptr != data_) - this->deallocate(old_ptr, old_capacity); + std::size_t new_capacity = + (std::max)(size, this->capacity_ + this->capacity_ / 2); + T *new_ptr = this->allocate(new_capacity); + // The following code doesn't throw, so the raw pointer above doesn't leak. + std::copy(this->ptr_, + this->ptr_ + this->size_, make_ptr(new_ptr, new_capacity)); + std::size_t old_capacity = this->capacity_; + T *old_ptr = this->ptr_; + this->capacity_ = new_capacity; + this->ptr_ = new_ptr; + // deallocate may throw (at least in principle), but it doesn't matter since + // the buffer already uses the new storage and will deallocate it in case + // of exception. + if (old_ptr != data_) + this->deallocate(old_ptr, old_capacity); } #ifndef _MSC_VER // Portable version of signbit. inline int getsign(double x) { - // When compiled in C++11 mode signbit is no longer a macro but a function - // defined in namespace std and the macro is undefined. + // When compiled in C++11 mode signbit is no longer a macro but a function + // defined in namespace std and the macro is undefined. # ifdef signbit - return signbit(x); + return signbit(x); # else - return std::signbit(x); + return std::signbit(x); # endif } @@ -453,48 +453,48 @@ inline int getsign(double x) # ifdef isinf inline int isinfinity(double x) { - return isinf(x); + return isinf(x); } inline int isinfinity(long double x) { - return isinf(x); + return isinf(x); } # else inline int isinfinity(double x) { - return std::isinf(x); + return std::isinf(x); } inline int isinfinity(long double x) { - return std::isinf(x); + return std::isinf(x); } # endif #else inline int getsign(double value) { - if (value < 0) return 1; - if (value == value) return 0; - int dec = 0, sign = 0; - char buffer[2]; // The buffer size must be >= 2 or _ecvt_s will fail. - _ecvt_s(buffer, sizeof(buffer), value, 0, &dec, &sign); - return sign; + if (value < 0) return 1; + if (value == value) return 0; + int dec = 0, sign = 0; + char buffer[2]; // The buffer size must be >= 2 or _ecvt_s will fail. + _ecvt_s(buffer, sizeof(buffer), value, 0, &dec, &sign); + return sign; } inline int isinfinity(double x) { - return !_finite(x); + return !_finite(x); } #endif template struct IsLongDouble { - enum { VALUE = 0 }; + enum { VALUE = 0 }; }; template <> struct IsLongDouble { - enum { VALUE = 1 }; + enum { VALUE = 1 }; }; template @@ -502,9 +502,9 @@ class BasicCharTraits { public: #if _SECURE_SCL - typedef stdext::checked_array_iterator CharPtr; + typedef stdext::checked_array_iterator CharPtr; #else - typedef Char *CharPtr; + typedef Char *CharPtr; #endif }; @@ -515,62 +515,62 @@ template <> class CharTraits : public BasicCharTraits { private: - // Conversion from wchar_t to char is not allowed. - static char convert(wchar_t); + // Conversion from wchar_t to char is not allowed. + static char convert(wchar_t); public: - typedef const wchar_t *UnsupportedStrType; + typedef const wchar_t *UnsupportedStrType; - static char convert(char value) - { - return value; - } + static char convert(char value) + { + return value; + } - // Formats a floating-point number. - template - static int format_float(char *buffer, std::size_t size, - const char *format, unsigned width, int precision, T value); + // Formats a floating-point number. + template + static int format_float(char *buffer, std::size_t size, + const char *format, unsigned width, int precision, T value); }; template <> class CharTraits : public BasicCharTraits { public: - typedef const char *UnsupportedStrType; + typedef const char *UnsupportedStrType; - static wchar_t convert(char value) - { - return value; - } - static wchar_t convert(wchar_t value) - { - return value; - } + static wchar_t convert(char value) + { + return value; + } + static wchar_t convert(wchar_t value) + { + return value; + } - template - static int format_float(wchar_t *buffer, std::size_t size, - const wchar_t *format, unsigned width, int precision, T value); + template + static int format_float(wchar_t *buffer, std::size_t size, + const wchar_t *format, unsigned width, int precision, T value); }; // Checks if a number is negative - used to avoid warnings. template struct SignChecker { - template - static bool is_negative(T value) - { - return value < 0; - } + template + static bool is_negative(T value) + { + return value < 0; + } }; template <> struct SignChecker { - template - static bool is_negative(T) - { - return false; - } + template + static bool is_negative(T) + { + return false; + } }; // Returns true if value is negative, false otherwise. @@ -578,36 +578,36 @@ struct SignChecker template inline bool is_negative(T value) { - return SignChecker::is_signed>::is_negative(value); + return SignChecker::is_signed>::is_negative(value); } // Selects uint32_t if FitsIn32Bits is true, uint64_t otherwise. template struct TypeSelector { - typedef uint32_t Type; + typedef uint32_t Type; }; template <> struct TypeSelector { - typedef uint64_t Type; + typedef uint64_t Type; }; template struct IntTraits { - // Smallest of uint32_t and uint64_t that is large enough to represent - // all values of T. - typedef typename - TypeSelector::digits <= 32>::Type MainType; + // Smallest of uint32_t and uint64_t that is large enough to represent + // all values of T. + typedef typename + TypeSelector::digits <= 32>::Type MainType; }; // MakeUnsigned::Type gives an unsigned type corresponding to integer type T. template struct MakeUnsigned { - typedef T Type; + typedef T Type; }; #define FMT_SPECIALIZE_MAKE_UNSIGNED(T, U) \ @@ -628,9 +628,9 @@ void report_unknown_type(char code, const char *type); template struct BasicData { - static const uint32_t POWERS_OF_10_32[]; - static const uint64_t POWERS_OF_10_64[]; - static const char DIGITS[]; + static const uint32_t POWERS_OF_10_32[]; + static const uint64_t POWERS_OF_10_64[]; + static const char DIGITS[]; }; typedef BasicData<> Data; @@ -640,36 +640,36 @@ typedef BasicData<> Data; // except for n == 0 in which case count_digits returns 1. inline unsigned count_digits(uint64_t n) { - // Based on http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10 - // and the benchmark https://github.com/localvoid/cxx-benchmark-count-digits. - unsigned t = (64 - __builtin_clzll(n | 1)) * 1233 >> 12; - return t - (n < Data::POWERS_OF_10_64[t]) + 1; + // Based on http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10 + // and the benchmark https://github.com/localvoid/cxx-benchmark-count-digits. + unsigned t = (64 - __builtin_clzll(n | 1)) * 1233 >> 12; + return t - (n < Data::POWERS_OF_10_64[t]) + 1; } # if FMT_GCC_VERSION >= 400 || FMT_HAS_BUILTIN(__builtin_clz) // Optional version of count_digits for better performance on 32-bit platforms. inline unsigned count_digits(uint32_t n) { - uint32_t t = (32 - __builtin_clz(n | 1)) * 1233 >> 12; - return t - (n < Data::POWERS_OF_10_32[t]) + 1; + uint32_t t = (32 - __builtin_clz(n | 1)) * 1233 >> 12; + return t - (n < Data::POWERS_OF_10_32[t]) + 1; } # endif #else // Fallback version of count_digits used when __builtin_clz is not available. inline unsigned count_digits(uint64_t n) { - unsigned count = 1; - for (;;) - { - // Integer division is slow so do it for a group of four digits instead - // of for every digit. The idea comes from the talk by Alexandrescu - // "Three Optimization Tips for C++". See speed-test for a comparison. - if (n < 10) return count; - if (n < 100) return count + 1; - if (n < 1000) return count + 2; - if (n < 10000) return count + 3; - n /= 10000u; - count += 4; - } + unsigned count = 1; + for (;;) + { + // Integer division is slow so do it for a group of four digits instead + // of for every digit. The idea comes from the talk by Alexandrescu + // "Three Optimization Tips for C++". See speed-test for a comparison. + if (n < 10) return count; + if (n < 100) return count + 1; + if (n < 1000) return count + 2; + if (n < 10000) return count + 3; + n /= 10000u; + count += 4; + } } #endif @@ -677,26 +677,26 @@ inline unsigned count_digits(uint64_t n) template inline void format_decimal(Char *buffer, UInt value, unsigned num_digits) { - --num_digits; - while (value >= 100) - { - // Integer division is slow so do it for a group of two digits instead - // of for every digit. The idea comes from the talk by Alexandrescu - // "Three Optimization Tips for C++". See speed-test for a comparison. - unsigned index = (value % 100) * 2; - value /= 100; - buffer[num_digits] = Data::DIGITS[index + 1]; - buffer[num_digits - 1] = Data::DIGITS[index]; - num_digits -= 2; - } - if (value < 10) - { - *buffer = static_cast('0' + value); - return; - } - unsigned index = static_cast(value * 2); - buffer[1] = Data::DIGITS[index + 1]; - buffer[0] = Data::DIGITS[index]; + --num_digits; + while (value >= 100) + { + // Integer division is slow so do it for a group of two digits instead + // of for every digit. The idea comes from the talk by Alexandrescu + // "Three Optimization Tips for C++". See speed-test for a comparison. + unsigned index = (value % 100) * 2; + value /= 100; + buffer[num_digits] = Data::DIGITS[index + 1]; + buffer[num_digits - 1] = Data::DIGITS[index]; + num_digits -= 2; + } + if (value < 10) + { + *buffer = static_cast('0' + value); + return; + } + unsigned index = static_cast(value * 2); + buffer[1] = Data::DIGITS[index + 1]; + buffer[0] = Data::DIGITS[index]; } #ifdef _WIN32 @@ -705,26 +705,26 @@ inline void format_decimal(Char *buffer, UInt value, unsigned num_digits) class UTF8ToUTF16 { private: - MemoryBuffer buffer_; + MemoryBuffer buffer_; public: - explicit UTF8ToUTF16(StringRef s); - operator WStringRef() const - { - return WStringRef(&buffer_[0], size()); - } - size_t size() const - { - return buffer_.size() - 1; - } - const wchar_t *c_str() const - { - return &buffer_[0]; - } - std::wstring str() const - { - return std::wstring(&buffer_[0], size()); - } + explicit UTF8ToUTF16(StringRef s); + operator WStringRef() const + { + return WStringRef(&buffer_[0], size()); + } + size_t size() const + { + return buffer_.size() - 1; + } + const wchar_t *c_str() const + { + return &buffer_[0]; + } + std::wstring str() const + { + return std::wstring(&buffer_[0], size()); + } }; // A converter from UTF-16 to UTF-8. @@ -732,32 +732,32 @@ public: class UTF16ToUTF8 { private: - MemoryBuffer buffer_; + MemoryBuffer buffer_; public: - UTF16ToUTF8() {} - explicit UTF16ToUTF8(WStringRef s); - operator StringRef() const - { - return StringRef(&buffer_[0], size()); - } - size_t size() const - { - return buffer_.size() - 1; - } - const char *c_str() const - { - return &buffer_[0]; - } - std::string str() const - { - return std::string(&buffer_[0], size()); - } + UTF16ToUTF8() {} + explicit UTF16ToUTF8(WStringRef s); + operator StringRef() const + { + return StringRef(&buffer_[0], size()); + } + size_t size() const + { + return buffer_.size() - 1; + } + const char *c_str() const + { + return &buffer_[0]; + } + std::string str() const + { + return std::string(&buffer_[0], size()); + } - // Performs conversion returning a system error code instead of - // throwing exception on conversion error. This method may still throw - // in case of memory allocation error. - int convert(WStringRef s); + // Performs conversion returning a system error code instead of + // throwing exception on conversion error. This method may still throw + // in case of memory allocation error. + int convert(WStringRef s); }; #endif @@ -774,64 +774,64 @@ void format_windows_error(fmt::Writer &out, int error_code, template struct NonZero { - enum { VALUE = Arg }; + enum { VALUE = Arg }; }; template <> struct NonZero<0> { - enum { VALUE = 1 }; + enum { VALUE = 1 }; }; // The value of a formatting argument. It is a POD type to allow storage in // internal::MemoryBuffer. struct Value { - template - struct StringValue - { - const Char *value; - std::size_t size; - }; + template + struct StringValue + { + const Char *value; + std::size_t size; + }; - typedef void(*FormatFunc)( - void *formatter, const void *arg, void *format_str_ptr); + typedef void(*FormatFunc)( + void *formatter, const void *arg, void *format_str_ptr); - struct CustomValue - { - const void *value; - FormatFunc format; - }; + struct CustomValue + { + const void *value; + FormatFunc format; + }; - union - { - int int_value; - unsigned uint_value; - LongLong long_long_value; - ULongLong ulong_long_value; - double double_value; - long double long_double_value; - const void *pointer; - StringValue string; - StringValue sstring; - StringValue ustring; - StringValue wstring; - CustomValue custom; - }; + union + { + int int_value; + unsigned uint_value; + LongLong long_long_value; + ULongLong ulong_long_value; + double double_value; + long double long_double_value; + const void *pointer; + StringValue string; + StringValue sstring; + StringValue ustring; + StringValue wstring; + CustomValue custom; + }; }; struct Arg : Value { - enum Type - { - NONE, - // Integer types should go first, - INT, UINT, LONG_LONG, ULONG_LONG, CHAR, LAST_INTEGER_TYPE = CHAR, - // followed by floating-point types. - DOUBLE, LONG_DOUBLE, LAST_NUMERIC_TYPE = LONG_DOUBLE, - CSTRING, STRING, WSTRING, POINTER, CUSTOM - }; - Type type; + enum Type + { + NONE, + // Integer types should go first, + INT, UINT, LONG_LONG, ULONG_LONG, CHAR, LAST_INTEGER_TYPE = CHAR, + // followed by floating-point types. + DOUBLE, LONG_DOUBLE, LAST_NUMERIC_TYPE = LONG_DOUBLE, + CSTRING, STRING, WSTRING, POINTER, CUSTOM + }; + Type type; }; // Makes a Value object from any type. @@ -839,127 +839,127 @@ template class MakeValue : public Value { private: - // The following two methods are private to disallow formatting of - // arbitrary pointers. If you want to output a pointer cast it to - // "void *" or "const void *". In particular, this forbids formatting - // of "[const] volatile char *" which is printed as bool by iostreams. - // Do not implement! - template - MakeValue(const T *value); - template - MakeValue(T *value); + // The following two methods are private to disallow formatting of + // arbitrary pointers. If you want to output a pointer cast it to + // "void *" or "const void *". In particular, this forbids formatting + // of "[const] volatile char *" which is printed as bool by iostreams. + // Do not implement! + template + MakeValue(const T *value); + template + MakeValue(T *value); - void set_string(StringRef str) - { - string.value = str.c_str(); - string.size = str.size(); - } + void set_string(StringRef str) + { + string.value = str.c_str(); + string.size = str.size(); + } - void set_string(WStringRef str) - { - CharTraits::convert(wchar_t()); - wstring.value = str.c_str(); - wstring.size = str.size(); - } + void set_string(WStringRef str) + { + CharTraits::convert(wchar_t()); + wstring.value = str.c_str(); + wstring.size = str.size(); + } - // Formats an argument of a custom type, such as a user-defined class. - template - static void format_custom_arg( - void *formatter, const void *arg, void *format_str_ptr) - { - format(*static_cast*>(formatter), - *static_cast(format_str_ptr), - *static_cast(arg)); - } + // Formats an argument of a custom type, such as a user-defined class. + template + static void format_custom_arg( + void *formatter, const void *arg, void *format_str_ptr) + { + format(*static_cast*>(formatter), + *static_cast(format_str_ptr), + *static_cast(arg)); + } public: - MakeValue() {} + MakeValue() {} #define FMT_MAKE_VALUE(Type, field, TYPE) \ MakeValue(Type value) { field = value; } \ static uint64_t type(Type) { return Arg::TYPE; } - FMT_MAKE_VALUE(bool, int_value, INT) - FMT_MAKE_VALUE(short, int_value, INT) - FMT_MAKE_VALUE(unsigned short, uint_value, UINT) - FMT_MAKE_VALUE(int, int_value, INT) - FMT_MAKE_VALUE(unsigned, uint_value, UINT) + FMT_MAKE_VALUE(bool, int_value, INT) + FMT_MAKE_VALUE(short, int_value, INT) + FMT_MAKE_VALUE(unsigned short, uint_value, UINT) + FMT_MAKE_VALUE(int, int_value, INT) + FMT_MAKE_VALUE(unsigned, uint_value, UINT) - MakeValue(long value) - { - // To minimize the number of types we need to deal with, long is - // translated either to int or to long long depending on its size. - if (sizeof(long) == sizeof(int)) - int_value = static_cast(value); - else - long_long_value = value; - } - static uint64_t type(long) - { - return sizeof(long) == sizeof(int) ? Arg::INT : Arg::LONG_LONG; - } + MakeValue(long value) + { + // To minimize the number of types we need to deal with, long is + // translated either to int or to long long depending on its size. + if (sizeof(long) == sizeof(int)) + int_value = static_cast(value); + else + long_long_value = value; + } + static uint64_t type(long) + { + return sizeof(long) == sizeof(int) ? Arg::INT : Arg::LONG_LONG; + } - MakeValue(unsigned long value) - { - if (sizeof(unsigned long) == sizeof(unsigned)) - uint_value = static_cast(value); - else - ulong_long_value = value; - } - static uint64_t type(unsigned long) - { - return sizeof(unsigned long) == sizeof(unsigned) ? - Arg::UINT : Arg::ULONG_LONG; - } + MakeValue(unsigned long value) + { + if (sizeof(unsigned long) == sizeof(unsigned)) + uint_value = static_cast(value); + else + ulong_long_value = value; + } + static uint64_t type(unsigned long) + { + return sizeof(unsigned long) == sizeof(unsigned) ? + Arg::UINT : Arg::ULONG_LONG; + } - FMT_MAKE_VALUE(LongLong, long_long_value, LONG_LONG) - FMT_MAKE_VALUE(ULongLong, ulong_long_value, ULONG_LONG) - FMT_MAKE_VALUE(float, double_value, DOUBLE) - FMT_MAKE_VALUE(double, double_value, DOUBLE) - FMT_MAKE_VALUE(long double, long_double_value, LONG_DOUBLE) - FMT_MAKE_VALUE(signed char, int_value, CHAR) - FMT_MAKE_VALUE(unsigned char, int_value, CHAR) - FMT_MAKE_VALUE(char, int_value, CHAR) + FMT_MAKE_VALUE(LongLong, long_long_value, LONG_LONG) + FMT_MAKE_VALUE(ULongLong, ulong_long_value, ULONG_LONG) + FMT_MAKE_VALUE(float, double_value, DOUBLE) + FMT_MAKE_VALUE(double, double_value, DOUBLE) + FMT_MAKE_VALUE(long double, long_double_value, LONG_DOUBLE) + FMT_MAKE_VALUE(signed char, int_value, CHAR) + FMT_MAKE_VALUE(unsigned char, int_value, CHAR) + FMT_MAKE_VALUE(char, int_value, CHAR) - MakeValue(wchar_t value) - { - int_value = internal::CharTraits::convert(value); - } - static uint64_t type(wchar_t) - { - return Arg::CHAR; - } + MakeValue(wchar_t value) + { + int_value = internal::CharTraits::convert(value); + } + static uint64_t type(wchar_t) + { + return Arg::CHAR; + } #define FMT_MAKE_STR_VALUE(Type, TYPE) \ MakeValue(Type value) { set_string(value); } \ static uint64_t type(Type) { return Arg::TYPE; } - FMT_MAKE_VALUE(char *, string.value, CSTRING) - FMT_MAKE_VALUE(const char *, string.value, CSTRING) - FMT_MAKE_VALUE(const signed char *, sstring.value, CSTRING) - FMT_MAKE_VALUE(const unsigned char *, ustring.value, CSTRING) - FMT_MAKE_STR_VALUE(const std::string &, STRING) - FMT_MAKE_STR_VALUE(StringRef, STRING) + FMT_MAKE_VALUE(char *, string.value, CSTRING) + FMT_MAKE_VALUE(const char *, string.value, CSTRING) + FMT_MAKE_VALUE(const signed char *, sstring.value, CSTRING) + FMT_MAKE_VALUE(const unsigned char *, ustring.value, CSTRING) + FMT_MAKE_STR_VALUE(const std::string &, STRING) + FMT_MAKE_STR_VALUE(StringRef, STRING) - FMT_MAKE_STR_VALUE(wchar_t *, WSTRING) - FMT_MAKE_STR_VALUE(const wchar_t *, WSTRING) - FMT_MAKE_STR_VALUE(const std::wstring &, WSTRING) - FMT_MAKE_STR_VALUE(WStringRef, WSTRING) + FMT_MAKE_STR_VALUE(wchar_t *, WSTRING) + FMT_MAKE_STR_VALUE(const wchar_t *, WSTRING) + FMT_MAKE_STR_VALUE(const std::wstring &, WSTRING) + FMT_MAKE_STR_VALUE(WStringRef, WSTRING) - FMT_MAKE_VALUE(void *, pointer, POINTER) - FMT_MAKE_VALUE(const void *, pointer, POINTER) + FMT_MAKE_VALUE(void *, pointer, POINTER) + FMT_MAKE_VALUE(const void *, pointer, POINTER) - template - MakeValue(const T &value) - { - custom.value = &value; - custom.format = &format_custom_arg; - } - template - static uint64_t type(const T &) - { - return Arg::CUSTOM; - } + template + MakeValue(const T &value) + { + custom.value = &value; + custom.format = &format_custom_arg; + } + template + static uint64_t type(const T &) + { + return Arg::CUSTOM; + } }; #define FMT_DISPATCH(call) static_cast(this)->call @@ -988,111 +988,111 @@ template class ArgVisitor { public: - Result visit_unhandled_arg() - { - return Result(); - } + Result visit_unhandled_arg() + { + return Result(); + } - Result visit_int(int value) - { - return FMT_DISPATCH(visit_any_int(value)); - } - Result visit_long_long(LongLong value) - { - return FMT_DISPATCH(visit_any_int(value)); - } - Result visit_uint(unsigned value) - { - return FMT_DISPATCH(visit_any_int(value)); - } - Result visit_ulong_long(ULongLong value) - { - return FMT_DISPATCH(visit_any_int(value)); - } - Result visit_char(int value) - { - return FMT_DISPATCH(visit_any_int(value)); - } - template - Result visit_any_int(T) - { - return FMT_DISPATCH(visit_unhandled_arg()); - } + Result visit_int(int value) + { + return FMT_DISPATCH(visit_any_int(value)); + } + Result visit_long_long(LongLong value) + { + return FMT_DISPATCH(visit_any_int(value)); + } + Result visit_uint(unsigned value) + { + return FMT_DISPATCH(visit_any_int(value)); + } + Result visit_ulong_long(ULongLong value) + { + return FMT_DISPATCH(visit_any_int(value)); + } + Result visit_char(int value) + { + return FMT_DISPATCH(visit_any_int(value)); + } + template + Result visit_any_int(T) + { + return FMT_DISPATCH(visit_unhandled_arg()); + } - Result visit_double(double value) - { - return FMT_DISPATCH(visit_any_double(value)); - } - Result visit_long_double(long double value) - { - return FMT_DISPATCH(visit_any_double(value)); - } - template - Result visit_any_double(T) - { - return FMT_DISPATCH(visit_unhandled_arg()); - } + Result visit_double(double value) + { + return FMT_DISPATCH(visit_any_double(value)); + } + Result visit_long_double(long double value) + { + return FMT_DISPATCH(visit_any_double(value)); + } + template + Result visit_any_double(T) + { + return FMT_DISPATCH(visit_unhandled_arg()); + } - Result visit_string(Arg::StringValue) - { - return FMT_DISPATCH(visit_unhandled_arg()); - } - Result visit_wstring(Arg::StringValue) - { - return FMT_DISPATCH(visit_unhandled_arg()); - } - Result visit_pointer(const void *) - { - return FMT_DISPATCH(visit_unhandled_arg()); - } - Result visit_custom(Arg::CustomValue) - { - return FMT_DISPATCH(visit_unhandled_arg()); - } + Result visit_string(Arg::StringValue) + { + return FMT_DISPATCH(visit_unhandled_arg()); + } + Result visit_wstring(Arg::StringValue) + { + return FMT_DISPATCH(visit_unhandled_arg()); + } + Result visit_pointer(const void *) + { + return FMT_DISPATCH(visit_unhandled_arg()); + } + Result visit_custom(Arg::CustomValue) + { + return FMT_DISPATCH(visit_unhandled_arg()); + } - Result visit(const Arg &arg) - { - switch (arg.type) - { - default: - assert(false); - // Fall through. - case Arg::INT: - return FMT_DISPATCH(visit_int(arg.int_value)); - case Arg::UINT: - return FMT_DISPATCH(visit_uint(arg.uint_value)); - case Arg::LONG_LONG: - return FMT_DISPATCH(visit_long_long(arg.long_long_value)); - case Arg::ULONG_LONG: - return FMT_DISPATCH(visit_ulong_long(arg.ulong_long_value)); - case Arg::DOUBLE: - return FMT_DISPATCH(visit_double(arg.double_value)); - case Arg::LONG_DOUBLE: - return FMT_DISPATCH(visit_long_double(arg.long_double_value)); - case Arg::CHAR: - return FMT_DISPATCH(visit_char(arg.int_value)); - case Arg::CSTRING: - { - Value::StringValue str = arg.string; - str.size = 0; - return FMT_DISPATCH(visit_string(str)); - } - case Arg::STRING: - return FMT_DISPATCH(visit_string(arg.string)); - case Arg::WSTRING: - return FMT_DISPATCH(visit_wstring(arg.wstring)); - case Arg::POINTER: - return FMT_DISPATCH(visit_pointer(arg.pointer)); - case Arg::CUSTOM: - return FMT_DISPATCH(visit_custom(arg.custom)); - } - } + Result visit(const Arg &arg) + { + switch (arg.type) + { + default: + assert(false); + // Fall through. + case Arg::INT: + return FMT_DISPATCH(visit_int(arg.int_value)); + case Arg::UINT: + return FMT_DISPATCH(visit_uint(arg.uint_value)); + case Arg::LONG_LONG: + return FMT_DISPATCH(visit_long_long(arg.long_long_value)); + case Arg::ULONG_LONG: + return FMT_DISPATCH(visit_ulong_long(arg.ulong_long_value)); + case Arg::DOUBLE: + return FMT_DISPATCH(visit_double(arg.double_value)); + case Arg::LONG_DOUBLE: + return FMT_DISPATCH(visit_long_double(arg.long_double_value)); + case Arg::CHAR: + return FMT_DISPATCH(visit_char(arg.int_value)); + case Arg::CSTRING: + { + Value::StringValue str = arg.string; + str.size = 0; + return FMT_DISPATCH(visit_string(str)); + } + case Arg::STRING: + return FMT_DISPATCH(visit_string(arg.string)); + case Arg::WSTRING: + return FMT_DISPATCH(visit_wstring(arg.wstring)); + case Arg::POINTER: + return FMT_DISPATCH(visit_pointer(arg.pointer)); + case Arg::CUSTOM: + return FMT_DISPATCH(visit_custom(arg.custom)); + } + } }; class RuntimeError : public std::runtime_error { protected: - RuntimeError() : std::runtime_error("") {} + RuntimeError() : std::runtime_error("") {} }; template @@ -1105,41 +1105,41 @@ An argument list. class ArgList { private: - uint64_t types_; - const internal::Value *values_; + uint64_t types_; + const internal::Value *values_; public: - // Maximum number of arguments that can be passed in ArgList. - enum { MAX_ARGS = 16 }; + // Maximum number of arguments that can be passed in ArgList. + enum { MAX_ARGS = 16 }; - ArgList() : types_(0) {} - ArgList(ULongLong types, const internal::Value *values) - : types_(types), values_(values) {} + ArgList() : types_(0) {} + ArgList(ULongLong types, const internal::Value *values) + : types_(types), values_(values) {} - /** - Returns the argument at specified index. - */ - internal::Arg operator[](unsigned index) const - { - using internal::Arg; - Arg arg; - if (index >= MAX_ARGS) - { - arg.type = Arg::NONE; - return arg; - } - unsigned shift = index * 4; - uint64_t mask = 0xf; - Arg::Type type = - static_cast((types_ & (mask << shift)) >> shift); - arg.type = type; - if (type != Arg::NONE) - { - internal::Value &value = arg; - value = values_[index]; - } - return arg; - } + /** + Returns the argument at specified index. + */ + internal::Arg operator[](unsigned index) const + { + using internal::Arg; + Arg arg; + if (index >= MAX_ARGS) + { + arg.type = Arg::NONE; + return arg; + } + unsigned shift = index * 4; + uint64_t mask = 0xf; + Arg::Type type = + static_cast((types_ & (mask << shift)) >> shift); + arg.type = type; + if (type != Arg::NONE) + { + internal::Value &value = arg; + value = values_[index]; + } + return arg; + } }; struct FormatSpec; @@ -1150,32 +1150,32 @@ namespace internal class FormatterBase { private: - ArgList args_; - int next_arg_index_; + ArgList args_; + int next_arg_index_; - // Returns the argument with specified index. - Arg do_get_arg(unsigned arg_index, const char *&error); + // Returns the argument with specified index. + Arg do_get_arg(unsigned arg_index, const char *&error); protected: - void set_args(const ArgList &args) - { - args_ = args; - next_arg_index_ = 0; - } + void set_args(const ArgList &args) + { + args_ = args; + next_arg_index_ = 0; + } - // Returns the next argument. - Arg next_arg(const char *&error); + // Returns the next argument. + Arg next_arg(const char *&error); - // Checks if manual indexing is used and returns the argument with - // specified index. - Arg get_arg(unsigned arg_index, const char *&error); + // Checks if manual indexing is used and returns the argument with + // specified index. + Arg get_arg(unsigned arg_index, const char *&error); - template - void write(BasicWriter &w, const Char *start, const Char *end) - { - if (start != end) - w << BasicStringRef(start, end - start); - } + template + void write(BasicWriter &w, const Char *start, const Char *end) + { + if (start != end) + w << BasicStringRef(start, end - start); + } }; // A printf formatter. @@ -1183,19 +1183,19 @@ template class PrintfFormatter : private FormatterBase { private: - void parse_flags(FormatSpec &spec, const Char *&s); + void parse_flags(FormatSpec &spec, const Char *&s); - // Returns the argument with specified index or, if arg_index is equal - // to the maximum unsigned value, the next argument. - Arg get_arg(const Char *s, - unsigned arg_index = (std::numeric_limits::max)()); + // Returns the argument with specified index or, if arg_index is equal + // to the maximum unsigned value, the next argument. + Arg get_arg(const Char *s, + unsigned arg_index = (std::numeric_limits::max)()); - // Parses argument index, flags and width and returns the argument index. - unsigned parse_header(const Char *&s, FormatSpec &spec); + // Parses argument index, flags and width and returns the argument index. + unsigned parse_header(const Char *&s, FormatSpec &spec); public: - void format(BasicWriter &writer, - BasicStringRef format, const ArgList &args); + void format(BasicWriter &writer, + BasicStringRef format, const ArgList &args); }; } // namespace internal @@ -1204,23 +1204,23 @@ template class BasicFormatter : private internal::FormatterBase { private: - BasicWriter &writer_; - const Char *start_; + BasicWriter &writer_; + const Char *start_; - // Parses argument index and returns corresponding argument. - internal::Arg parse_arg_index(const Char *&s); + // Parses argument index and returns corresponding argument. + internal::Arg parse_arg_index(const Char *&s); public: - explicit BasicFormatter(BasicWriter &w) : writer_(w) {} + explicit BasicFormatter(BasicWriter &w) : writer_(w) {} - BasicWriter &writer() - { - return writer_; - } + BasicWriter &writer() + { + return writer_; + } - void format(BasicStringRef format_str, const ArgList &args); + void format(BasicStringRef format_str, const ArgList &args); - const Char *format(const Char *&format_str, const internal::Arg &arg); + const Char *format(const Char *&format_str, const internal::Arg &arg); }; enum Alignment @@ -1242,110 +1242,110 @@ struct EmptySpec {}; template struct TypeSpec : EmptySpec { - Alignment align() const - { - return ALIGN_DEFAULT; - } - unsigned width() const - { - return 0; - } - int precision() const - { - return -1; - } - bool flag(unsigned) const - { - return false; - } - char type() const - { - return TYPE; - } - char fill() const - { - return ' '; - } + Alignment align() const + { + return ALIGN_DEFAULT; + } + unsigned width() const + { + return 0; + } + int precision() const + { + return -1; + } + bool flag(unsigned) const + { + return false; + } + char type() const + { + return TYPE; + } + char fill() const + { + return ' '; + } }; // A width specifier. struct WidthSpec { - unsigned width_; - // Fill is always wchar_t and cast to char if necessary to avoid having - // two specialization of WidthSpec and its subclasses. - wchar_t fill_; + unsigned width_; + // Fill is always wchar_t and cast to char if necessary to avoid having + // two specialization of WidthSpec and its subclasses. + wchar_t fill_; - WidthSpec(unsigned width, wchar_t fill) : width_(width), fill_(fill) {} + WidthSpec(unsigned width, wchar_t fill) : width_(width), fill_(fill) {} - unsigned width() const - { - return width_; - } - wchar_t fill() const - { - return fill_; - } + unsigned width() const + { + return width_; + } + wchar_t fill() const + { + return fill_; + } }; // An alignment specifier. struct AlignSpec : WidthSpec { - Alignment align_; + Alignment align_; - AlignSpec(unsigned width, wchar_t fill, Alignment align = ALIGN_DEFAULT) - : WidthSpec(width, fill), align_(align) {} + AlignSpec(unsigned width, wchar_t fill, Alignment align = ALIGN_DEFAULT) + : WidthSpec(width, fill), align_(align) {} - Alignment align() const - { - return align_; - } + Alignment align() const + { + return align_; + } - int precision() const - { - return -1; - } + int precision() const + { + return -1; + } }; // An alignment and type specifier. template struct AlignTypeSpec : AlignSpec { - AlignTypeSpec(unsigned width, wchar_t fill) : AlignSpec(width, fill) {} + AlignTypeSpec(unsigned width, wchar_t fill) : AlignSpec(width, fill) {} - bool flag(unsigned) const - { - return false; - } - char type() const - { - return TYPE; - } + bool flag(unsigned) const + { + return false; + } + char type() const + { + return TYPE; + } }; // A full format specifier. struct FormatSpec : AlignSpec { - unsigned flags_; - int precision_; - char type_; + unsigned flags_; + int precision_; + char type_; - FormatSpec( - unsigned width = 0, char type = 0, wchar_t fill = ' ') - : AlignSpec(width, fill), flags_(0), precision_(-1), type_(type) {} + FormatSpec( + unsigned width = 0, char type = 0, wchar_t fill = ' ') + : AlignSpec(width, fill), flags_(0), precision_(-1), type_(type) {} - bool flag(unsigned f) const - { - return (flags_ & f) != 0; - } - int precision() const - { - return precision_; - } - char type() const - { - return type_; - } + bool flag(unsigned f) const + { + return (flags_ & f) != 0; + } + int precision() const + { + return precision_; + } + char type() const + { + return type_; + } }; // An integer format specifier. @@ -1353,16 +1353,16 @@ template , typename Char = char> class IntFormatSpec : public SpecT { private: - T value_; + T value_; public: - IntFormatSpec(T value, const SpecT &spec = SpecT()) - : SpecT(spec), value_(value) {} + IntFormatSpec(T value, const SpecT &spec = SpecT()) + : SpecT(spec), value_(value) {} - T value() const - { - return value_; - } + T value() const + { + return value_; + } }; // A string format specifier. @@ -1370,16 +1370,16 @@ template class StrFormatSpec : public AlignSpec { private: - const T *str_; + const T *str_; public: - StrFormatSpec(const T *str, unsigned width, wchar_t fill) - : AlignSpec(width, fill), str_(str) {} + StrFormatSpec(const T *str, unsigned width, wchar_t fill) + : AlignSpec(width, fill), str_(str) {} - const T *str() const - { - return str_; - } + const T *str() const + { + return str_; + } }; /** @@ -1494,13 +1494,13 @@ template inline StrFormatSpec pad( const Char *str, unsigned width, Char fill = ' ') { - return StrFormatSpec(str, width, fill); + return StrFormatSpec(str, width, fill); } inline StrFormatSpec pad( const wchar_t *str, unsigned width, char fill = ' ') { - return StrFormatSpec(str, width, fill); + return StrFormatSpec(str, width, fill); } // Generates a comma-separated list with results of applying f to @@ -1526,41 +1526,41 @@ namespace internal { inline uint64_t make_type() { - return 0; + return 0; } template inline uint64_t make_type(const T &arg) { - return MakeValue::type(arg); + return MakeValue::type(arg); } #if FMT_USE_VARIADIC_TEMPLATES template inline uint64_t make_type(const Arg &first, const Args & ... tail) { - return make_type(first) | (make_type(tail...) << 4); + return make_type(first) | (make_type(tail...) << 4); } #else struct ArgType { - uint64_t type; + uint64_t type; - ArgType() : type(0) {} + ArgType() : type(0) {} - template - ArgType(const T &arg) : type(make_type(arg)) {} + template + ArgType(const T &arg) : type(make_type(arg)) {} }; # define FMT_ARG_TYPE_DEFAULT(n) ArgType t##n = ArgType() inline uint64_t make_type(FMT_GEN15(FMT_ARG_TYPE_DEFAULT)) { - return t0.type | (t1.type << 4) | (t2.type << 8) | (t3.type << 12) | - (t4.type << 16) | (t5.type << 20) | (t6.type << 24) | (t7.type << 28) | - (t8.type << 32) | (t9.type << 36) | (t10.type << 40) | (t11.type << 44) | - (t12.type << 48) | (t13.type << 52) | (t14.type << 56); + return t0.type | (t1.type << 4) | (t2.type << 8) | (t3.type << 12) | + (t4.type << 16) | (t5.type << 20) | (t6.type << 24) | (t7.type << 28) | + (t8.type << 32) | (t9.type << 36) | (t10.type << 40) | (t11.type << 44) | + (t12.type << 48) | (t13.type << 52) | (t14.type << 56); } #endif } // namespace internal @@ -1669,35 +1669,35 @@ for example a file opening error. class SystemError : public internal::RuntimeError { private: - void init(int error_code, StringRef format_str, ArgList args); + void init(int error_code, StringRef format_str, ArgList args); protected: - int error_code_; + int error_code_; - typedef char Char; // For FMT_VARIADIC_CTOR. + typedef char Char; // For FMT_VARIADIC_CTOR. - SystemError() {} + SystemError() {} public: - /** - \rst - Constructs a :cpp:class:`fmt::SystemError` object with the description - of the form "**: **", where ** is the - formatted message and ** is the system message corresponding - to the error code. - *error_code* is a system error code as given by ``errno``. - \endrst - */ - SystemError(int error_code, StringRef message) - { - init(error_code, message, ArgList()); - } - FMT_VARIADIC_CTOR(SystemError, init, int, StringRef) + /** + \rst + Constructs a :cpp:class:`fmt::SystemError` object with the description + of the form "**: **", where ** is the + formatted message and ** is the system message corresponding + to the error code. + *error_code* is a system error code as given by ``errno``. + \endrst + */ + SystemError(int error_code, StringRef message) + { + init(error_code, message, ArgList()); + } + FMT_VARIADIC_CTOR(SystemError, init, int, StringRef) - int error_code() const - { - return error_code_; - } + int error_code() const + { + return error_code_; + } }; /** @@ -1722,251 +1722,251 @@ template class BasicWriter { private: - // Output buffer. - internal::Buffer &buffer_; + // Output buffer. + internal::Buffer &buffer_; - FMT_DISALLOW_COPY_AND_ASSIGN(BasicWriter); + FMT_DISALLOW_COPY_AND_ASSIGN(BasicWriter); - typedef typename internal::CharTraits::CharPtr CharPtr; + typedef typename internal::CharTraits::CharPtr CharPtr; #if _SECURE_SCL - // Returns pointer value. - static Char *get(CharPtr p) - { - return p.base(); - } + // Returns pointer value. + static Char *get(CharPtr p) + { + return p.base(); + } #else - static Char *get(Char *p) - { - return p; - } + static Char *get(Char *p) + { + return p; + } #endif - // Fills the padding around the content and returns the pointer to the - // content area. - static CharPtr fill_padding(CharPtr buffer, - unsigned total_size, std::size_t content_size, wchar_t fill); + // Fills the padding around the content and returns the pointer to the + // content area. + static CharPtr fill_padding(CharPtr buffer, + unsigned total_size, std::size_t content_size, wchar_t fill); - // Grows the buffer by n characters and returns a pointer to the newly - // allocated area. - CharPtr grow_buffer(std::size_t n) - { - std::size_t size = buffer_.size(); - buffer_.resize(size + n); - return internal::make_ptr(&buffer_[size], n); - } + // Grows the buffer by n characters and returns a pointer to the newly + // allocated area. + CharPtr grow_buffer(std::size_t n) + { + std::size_t size = buffer_.size(); + buffer_.resize(size + n); + return internal::make_ptr(&buffer_[size], n); + } - // Prepare a buffer for integer formatting. - CharPtr prepare_int_buffer(unsigned num_digits, - const EmptySpec &, const char *prefix, unsigned prefix_size) - { - unsigned size = prefix_size + num_digits; - CharPtr p = grow_buffer(size); - std::copy(prefix, prefix + prefix_size, p); - return p + size - 1; - } + // Prepare a buffer for integer formatting. + CharPtr prepare_int_buffer(unsigned num_digits, + const EmptySpec &, const char *prefix, unsigned prefix_size) + { + unsigned size = prefix_size + num_digits; + CharPtr p = grow_buffer(size); + std::copy(prefix, prefix + prefix_size, p); + return p + size - 1; + } - template - CharPtr prepare_int_buffer(unsigned num_digits, - const Spec &spec, const char *prefix, unsigned prefix_size); + template + CharPtr prepare_int_buffer(unsigned num_digits, + const Spec &spec, const char *prefix, unsigned prefix_size); - // Formats an integer. - template - void write_int(T value, Spec spec); + // Formats an integer. + template + void write_int(T value, Spec spec); - // Formats a floating-point number (double or long double). - template - void write_double(T value, const FormatSpec &spec); + // Formats a floating-point number (double or long double). + template + void write_double(T value, const FormatSpec &spec); - // Writes a formatted string. - template - CharPtr write_str( - const StrChar *s, std::size_t size, const AlignSpec &spec); + // Writes a formatted string. + template + CharPtr write_str( + const StrChar *s, std::size_t size, const AlignSpec &spec); - template - void write_str( - const internal::Arg::StringValue &str, const FormatSpec &spec); + template + void write_str( + const internal::Arg::StringValue &str, const FormatSpec &spec); - // This method is private to disallow writing a wide string to a - // char stream and vice versa. If you want to print a wide string - // as a pointer as std::ostream does, cast it to const void*. - // Do not implement! - void operator<<(typename internal::CharTraits::UnsupportedStrType); + // This method is private to disallow writing a wide string to a + // char stream and vice versa. If you want to print a wide string + // as a pointer as std::ostream does, cast it to const void*. + // Do not implement! + void operator<<(typename internal::CharTraits::UnsupportedStrType); - friend class internal::ArgFormatter; - friend class internal::PrintfFormatter; + friend class internal::ArgFormatter; + friend class internal::PrintfFormatter; protected: - /** - Constructs a ``BasicWriter`` object. - */ - explicit BasicWriter(internal::Buffer &b) : buffer_(b) {} + /** + Constructs a ``BasicWriter`` object. + */ + explicit BasicWriter(internal::Buffer &b) : buffer_(b) {} public: - /** - Destroys a ``BasicWriter`` object. - */ - virtual ~BasicWriter() {} + /** + Destroys a ``BasicWriter`` object. + */ + virtual ~BasicWriter() {} - /** - Returns the total number of characters written. - */ - std::size_t size() const - { - return buffer_.size(); - } + /** + Returns the total number of characters written. + */ + std::size_t size() const + { + return buffer_.size(); + } - /** - Returns a pointer to the output buffer content. No terminating null - character is appended. - */ - const Char *data() const FMT_NOEXCEPT(true) - { - return &buffer_[0]; - } + /** + Returns a pointer to the output buffer content. No terminating null + character is appended. + */ + const Char *data() const FMT_NOEXCEPT(true) + { + return &buffer_[0]; + } - /** - Returns a pointer to the output buffer content with terminating null - character appended. - */ - const Char *c_str() const - { - std::size_t size = buffer_.size(); - buffer_.reserve(size + 1); - buffer_[size] = '\0'; - return &buffer_[0]; - } + /** + Returns a pointer to the output buffer content with terminating null + character appended. + */ + const Char *c_str() const + { + std::size_t size = buffer_.size(); + buffer_.reserve(size + 1); + buffer_[size] = '\0'; + return &buffer_[0]; + } - /** - Returns the content of the output buffer as an `std::string`. - */ - std::basic_string str() const - { - return std::basic_string(&buffer_[0], buffer_.size()); - } + /** + Returns the content of the output buffer as an `std::string`. + */ + std::basic_string str() const + { + return std::basic_string(&buffer_[0], buffer_.size()); + } - /** - \rst - Writes formatted data. + /** + \rst + Writes formatted data. - *args* is an argument list representing arbitrary arguments. + *args* is an argument list representing arbitrary arguments. - **Example**:: + **Example**:: - MemoryWriter out; - out.write("Current point:\n"); - out.write("({:+f}, {:+f})", -3.14, 3.14); + MemoryWriter out; + out.write("Current point:\n"); + out.write("({:+f}, {:+f})", -3.14, 3.14); - This will write the following output to the ``out`` object: + This will write the following output to the ``out`` object: - .. code-block:: none + .. code-block:: none - Current point: - (-3.140000, +3.140000) + Current point: + (-3.140000, +3.140000) - The output can be accessed using :meth:`data`, :meth:`c_str` or :meth:`str` - methods. + The output can be accessed using :meth:`data`, :meth:`c_str` or :meth:`str` + methods. - See also :ref:`syntax`. - \endrst - */ - void write(BasicStringRef format, ArgList args) - { - BasicFormatter(*this).format(format, args); - } - FMT_VARIADIC_VOID(write, BasicStringRef) + See also :ref:`syntax`. + \endrst + */ + void write(BasicStringRef format, ArgList args) + { + BasicFormatter(*this).format(format, args); + } + FMT_VARIADIC_VOID(write, BasicStringRef) - BasicWriter &operator<<(int value) - { - return *this << IntFormatSpec(value); - } - BasicWriter &operator<<(unsigned value) - { - return *this << IntFormatSpec(value); - } - BasicWriter &operator<<(long value) - { - return *this << IntFormatSpec(value); - } - BasicWriter &operator<<(unsigned long value) - { - return *this << IntFormatSpec(value); - } - BasicWriter &operator<<(LongLong value) - { - return *this << IntFormatSpec(value); - } + BasicWriter &operator<<(int value) + { + return *this << IntFormatSpec(value); + } + BasicWriter &operator<<(unsigned value) + { + return *this << IntFormatSpec(value); + } + BasicWriter &operator<<(long value) + { + return *this << IntFormatSpec(value); + } + BasicWriter &operator<<(unsigned long value) + { + return *this << IntFormatSpec(value); + } + BasicWriter &operator<<(LongLong value) + { + return *this << IntFormatSpec(value); + } - /** - Formats *value* and writes it to the stream. - */ - BasicWriter &operator<<(ULongLong value) - { - return *this << IntFormatSpec(value); - } + /** + Formats *value* and writes it to the stream. + */ + BasicWriter &operator<<(ULongLong value) + { + return *this << IntFormatSpec(value); + } - BasicWriter &operator<<(double value) - { - write_double(value, FormatSpec()); - return *this; - } + BasicWriter &operator<<(double value) + { + write_double(value, FormatSpec()); + return *this; + } - /** - Formats *value* using the general format for floating-point numbers - (``'g'``) and writes it to the stream. - */ - BasicWriter &operator<<(long double value) - { - write_double(value, FormatSpec()); - return *this; - } + /** + Formats *value* using the general format for floating-point numbers + (``'g'``) and writes it to the stream. + */ + BasicWriter &operator<<(long double value) + { + write_double(value, FormatSpec()); + return *this; + } - /** - Writes a character to the stream. - */ - BasicWriter &operator<<(char value) - { - buffer_.push_back(value); - return *this; - } + /** + Writes a character to the stream. + */ + BasicWriter &operator<<(char value) + { + buffer_.push_back(value); + return *this; + } - BasicWriter &operator<<(wchar_t value) - { - buffer_.push_back(internal::CharTraits::convert(value)); - return *this; - } + BasicWriter &operator<<(wchar_t value) + { + buffer_.push_back(internal::CharTraits::convert(value)); + return *this; + } - /** - Writes *value* to the stream. - */ - BasicWriter &operator<<(fmt::BasicStringRef value) - { - const Char *str = value.c_str(); - buffer_.append(str, str + value.size()); - return *this; - } + /** + Writes *value* to the stream. + */ + BasicWriter &operator<<(fmt::BasicStringRef value) + { + const Char *str = value.c_str(); + buffer_.append(str, str + value.size()); + return *this; + } - template - BasicWriter &operator<<(IntFormatSpec spec) - { - internal::CharTraits::convert(FillChar()); - write_int(spec.value(), spec); - return *this; - } + template + BasicWriter &operator<<(IntFormatSpec spec) + { + internal::CharTraits::convert(FillChar()); + write_int(spec.value(), spec); + return *this; + } - template - BasicWriter &operator<<(const StrFormatSpec &spec) - { - const StrChar *s = spec.str(); - // TODO: error if fill is not convertible to Char - write_str(s, std::char_traits::length(s), spec); - return *this; - } + template + BasicWriter &operator<<(const StrFormatSpec &spec) + { + const StrChar *s = spec.str(); + // TODO: error if fill is not convertible to Char + write_str(s, std::char_traits::length(s), spec); + return *this; + } - void clear() FMT_NOEXCEPT(true) - { - buffer_.clear(); - } + void clear() FMT_NOEXCEPT(true) + { + buffer_.clear(); + } }; template @@ -1974,31 +1974,31 @@ template typename BasicWriter::CharPtr BasicWriter::write_str( const StrChar *s, std::size_t size, const AlignSpec &spec) { - CharPtr out = CharPtr(); - if (spec.width() > size) - { - out = grow_buffer(spec.width()); - Char fill = static_cast(spec.fill()); - if (spec.align() == ALIGN_RIGHT) - { - std::fill_n(out, spec.width() - size, fill); - out += spec.width() - size; - } - else if (spec.align() == ALIGN_CENTER) - { - out = fill_padding(out, spec.width(), size, fill); - } - else - { - std::fill_n(out + size, spec.width() - size, fill); - } - } - else - { - out = grow_buffer(size); - } - std::copy(s, s + size, out); - return out; + CharPtr out = CharPtr(); + if (spec.width() > size) + { + out = grow_buffer(spec.width()); + Char fill = static_cast(spec.fill()); + if (spec.align() == ALIGN_RIGHT) + { + std::fill_n(out, spec.width() - size, fill); + out += spec.width() - size; + } + else if (spec.align() == ALIGN_CENTER) + { + out = fill_padding(out, spec.width(), size, fill); + } + else + { + std::fill_n(out + size, spec.width() - size, fill); + } + } + else + { + out = grow_buffer(size); + } + std::copy(s, s + size, out); + return out; } template @@ -2007,14 +2007,14 @@ BasicWriter::fill_padding( CharPtr buffer, unsigned total_size, std::size_t content_size, wchar_t fill) { - std::size_t padding = total_size - content_size; - std::size_t left_padding = padding / 2; - Char fill_char = static_cast(fill); - std::fill_n(buffer, left_padding, fill_char); - buffer += left_padding; - CharPtr content = buffer; - std::fill_n(buffer + content_size, padding - left_padding, fill_char); - return content; + std::size_t padding = total_size - content_size; + std::size_t left_padding = padding / 2; + Char fill_char = static_cast(fill); + std::fill_n(buffer, left_padding, fill_char); + buffer += left_padding; + CharPtr content = buffer; + std::fill_n(buffer + content_size, padding - left_padding, fill_char); + return content; } template @@ -2024,182 +2024,182 @@ BasicWriter::prepare_int_buffer( unsigned num_digits, const Spec &spec, const char *prefix, unsigned prefix_size) { - unsigned width = spec.width(); - Alignment align = spec.align(); - Char fill = static_cast(spec.fill()); - if (spec.precision() > static_cast(num_digits)) - { - // Octal prefix '0' is counted as a digit, so ignore it if precision - // is specified. - if (prefix_size > 0 && prefix[prefix_size - 1] == '0') - --prefix_size; - unsigned number_size = prefix_size + spec.precision(); - AlignSpec subspec(number_size, '0', ALIGN_NUMERIC); - if (number_size >= width) - return prepare_int_buffer(num_digits, subspec, prefix, prefix_size); - buffer_.reserve(width); - unsigned fill_size = width - number_size; - if (align != ALIGN_LEFT) - { - CharPtr p = grow_buffer(fill_size); - std::fill(p, p + fill_size, fill); - } - CharPtr result = prepare_int_buffer( - num_digits, subspec, prefix, prefix_size); - if (align == ALIGN_LEFT) - { - CharPtr p = grow_buffer(fill_size); - std::fill(p, p + fill_size, fill); - } - return result; - } - unsigned size = prefix_size + num_digits; - if (width <= size) - { - CharPtr p = grow_buffer(size); - std::copy(prefix, prefix + prefix_size, p); - return p + size - 1; - } - CharPtr p = grow_buffer(width); - CharPtr end = p + width; - if (align == ALIGN_LEFT) - { - std::copy(prefix, prefix + prefix_size, p); - p += size; - std::fill(p, end, fill); - } - else if (align == ALIGN_CENTER) - { - p = fill_padding(p, width, size, fill); - std::copy(prefix, prefix + prefix_size, p); - p += size; - } - else - { - if (align == ALIGN_NUMERIC) - { - if (prefix_size != 0) - { - p = std::copy(prefix, prefix + prefix_size, p); - size -= prefix_size; - } - } - else - { - std::copy(prefix, prefix + prefix_size, end - size); - } - std::fill(p, end - size, fill); - p = end; - } - return p - 1; + unsigned width = spec.width(); + Alignment align = spec.align(); + Char fill = static_cast(spec.fill()); + if (spec.precision() > static_cast(num_digits)) + { + // Octal prefix '0' is counted as a digit, so ignore it if precision + // is specified. + if (prefix_size > 0 && prefix[prefix_size - 1] == '0') + --prefix_size; + unsigned number_size = prefix_size + spec.precision(); + AlignSpec subspec(number_size, '0', ALIGN_NUMERIC); + if (number_size >= width) + return prepare_int_buffer(num_digits, subspec, prefix, prefix_size); + buffer_.reserve(width); + unsigned fill_size = width - number_size; + if (align != ALIGN_LEFT) + { + CharPtr p = grow_buffer(fill_size); + std::fill(p, p + fill_size, fill); + } + CharPtr result = prepare_int_buffer( + num_digits, subspec, prefix, prefix_size); + if (align == ALIGN_LEFT) + { + CharPtr p = grow_buffer(fill_size); + std::fill(p, p + fill_size, fill); + } + return result; + } + unsigned size = prefix_size + num_digits; + if (width <= size) + { + CharPtr p = grow_buffer(size); + std::copy(prefix, prefix + prefix_size, p); + return p + size - 1; + } + CharPtr p = grow_buffer(width); + CharPtr end = p + width; + if (align == ALIGN_LEFT) + { + std::copy(prefix, prefix + prefix_size, p); + p += size; + std::fill(p, end, fill); + } + else if (align == ALIGN_CENTER) + { + p = fill_padding(p, width, size, fill); + std::copy(prefix, prefix + prefix_size, p); + p += size; + } + else + { + if (align == ALIGN_NUMERIC) + { + if (prefix_size != 0) + { + p = std::copy(prefix, prefix + prefix_size, p); + size -= prefix_size; + } + } + else + { + std::copy(prefix, prefix + prefix_size, end - size); + } + std::fill(p, end - size, fill); + p = end; + } + return p - 1; } template template void BasicWriter::write_int(T value, Spec spec) { - unsigned prefix_size = 0; - typedef typename internal::IntTraits::MainType UnsignedType; - UnsignedType abs_value = value; - char prefix[4] = ""; - if (internal::is_negative(value)) - { - prefix[0] = '-'; - ++prefix_size; - abs_value = 0 - abs_value; - } - else if (spec.flag(SIGN_FLAG)) - { - prefix[0] = spec.flag(PLUS_FLAG) ? '+' : ' '; - ++prefix_size; - } - switch (spec.type()) - { - case 0: - case 'd': - { - unsigned num_digits = internal::count_digits(abs_value); - CharPtr p = prepare_int_buffer( - num_digits, spec, prefix, prefix_size) + 1 - num_digits; - internal::format_decimal(get(p), abs_value, num_digits); - break; - } - case 'x': - case 'X': - { - UnsignedType n = abs_value; - if (spec.flag(HASH_FLAG)) - { - prefix[prefix_size++] = '0'; - prefix[prefix_size++] = spec.type(); - } - unsigned num_digits = 0; - do - { - ++num_digits; - } - while ((n >>= 4) != 0); - Char *p = get(prepare_int_buffer( - num_digits, spec, prefix, prefix_size)); - n = abs_value; - const char *digits = spec.type() == 'x' ? - "0123456789abcdef" : "0123456789ABCDEF"; - do - { - *p-- = digits[n & 0xf]; - } - while ((n >>= 4) != 0); - break; - } - case 'b': - case 'B': - { - UnsignedType n = abs_value; - if (spec.flag(HASH_FLAG)) - { - prefix[prefix_size++] = '0'; - prefix[prefix_size++] = spec.type(); - } - unsigned num_digits = 0; - do - { - ++num_digits; - } - while ((n >>= 1) != 0); - Char *p = get(prepare_int_buffer(num_digits, spec, prefix, prefix_size)); - n = abs_value; - do - { - *p-- = '0' + (n & 1); - } - while ((n >>= 1) != 0); - break; - } - case 'o': - { - UnsignedType n = abs_value; - if (spec.flag(HASH_FLAG)) - prefix[prefix_size++] = '0'; - unsigned num_digits = 0; - do - { - ++num_digits; - } - while ((n >>= 3) != 0); - Char *p = get(prepare_int_buffer(num_digits, spec, prefix, prefix_size)); - n = abs_value; - do - { - *p-- = '0' + (n & 7); - } - while ((n >>= 3) != 0); - break; - } - default: - internal::report_unknown_type( - spec.type(), spec.flag(CHAR_FLAG) ? "char" : "integer"); - break; - } + unsigned prefix_size = 0; + typedef typename internal::IntTraits::MainType UnsignedType; + UnsignedType abs_value = value; + char prefix[4] = ""; + if (internal::is_negative(value)) + { + prefix[0] = '-'; + ++prefix_size; + abs_value = 0 - abs_value; + } + else if (spec.flag(SIGN_FLAG)) + { + prefix[0] = spec.flag(PLUS_FLAG) ? '+' : ' '; + ++prefix_size; + } + switch (spec.type()) + { + case 0: + case 'd': + { + unsigned num_digits = internal::count_digits(abs_value); + CharPtr p = prepare_int_buffer( + num_digits, spec, prefix, prefix_size) + 1 - num_digits; + internal::format_decimal(get(p), abs_value, num_digits); + break; + } + case 'x': + case 'X': + { + UnsignedType n = abs_value; + if (spec.flag(HASH_FLAG)) + { + prefix[prefix_size++] = '0'; + prefix[prefix_size++] = spec.type(); + } + unsigned num_digits = 0; + do + { + ++num_digits; + } + while ((n >>= 4) != 0); + Char *p = get(prepare_int_buffer( + num_digits, spec, prefix, prefix_size)); + n = abs_value; + const char *digits = spec.type() == 'x' ? + "0123456789abcdef" : "0123456789ABCDEF"; + do + { + *p-- = digits[n & 0xf]; + } + while ((n >>= 4) != 0); + break; + } + case 'b': + case 'B': + { + UnsignedType n = abs_value; + if (spec.flag(HASH_FLAG)) + { + prefix[prefix_size++] = '0'; + prefix[prefix_size++] = spec.type(); + } + unsigned num_digits = 0; + do + { + ++num_digits; + } + while ((n >>= 1) != 0); + Char *p = get(prepare_int_buffer(num_digits, spec, prefix, prefix_size)); + n = abs_value; + do + { + *p-- = '0' + (n & 1); + } + while ((n >>= 1) != 0); + break; + } + case 'o': + { + UnsignedType n = abs_value; + if (spec.flag(HASH_FLAG)) + prefix[prefix_size++] = '0'; + unsigned num_digits = 0; + do + { + ++num_digits; + } + while ((n >>= 3) != 0); + Char *p = get(prepare_int_buffer(num_digits, spec, prefix, prefix_size)); + n = abs_value; + do + { + *p-- = '0' + (n & 7); + } + while ((n >>= 3) != 0); + break; + } + default: + internal::report_unknown_type( + spec.type(), spec.flag(CHAR_FLAG) ? "char" : "integer"); + break; + } } template @@ -2207,178 +2207,178 @@ template void BasicWriter::write_double( T value, const FormatSpec &spec) { - // Check type. - char type = spec.type(); - bool upper = false; - switch (type) - { - case 0: - type = 'g'; - break; - case 'e': - case 'f': - case 'g': - case 'a': - break; - case 'F': + // Check type. + char type = spec.type(); + bool upper = false; + switch (type) + { + case 0: + type = 'g'; + break; + case 'e': + case 'f': + case 'g': + case 'a': + break; + case 'F': #ifdef _MSC_VER - // MSVC's printf doesn't support 'F'. - type = 'f'; + // MSVC's printf doesn't support 'F'. + type = 'f'; #endif - // Fall through. - case 'E': - case 'G': - case 'A': - upper = true; - break; - default: - internal::report_unknown_type(type, "double"); - break; - } + // Fall through. + case 'E': + case 'G': + case 'A': + upper = true; + break; + default: + internal::report_unknown_type(type, "double"); + break; + } - char sign = 0; - // Use getsign instead of value < 0 because the latter is always - // false for NaN. - if (internal::getsign(static_cast(value))) - { - sign = '-'; - value = -value; - } - else if (spec.flag(SIGN_FLAG)) - { - sign = spec.flag(PLUS_FLAG) ? '+' : ' '; - } + char sign = 0; + // Use getsign instead of value < 0 because the latter is always + // false for NaN. + if (internal::getsign(static_cast(value))) + { + sign = '-'; + value = -value; + } + else if (spec.flag(SIGN_FLAG)) + { + sign = spec.flag(PLUS_FLAG) ? '+' : ' '; + } - if (value != value) - { - // Format NaN ourselves because sprintf's output is not consistent - // across platforms. - std::size_t size = 4; - const char *nan = upper ? " NAN" : " nan"; - if (!sign) - { - --size; - ++nan; - } - CharPtr out = write_str(nan, size, spec); - if (sign) - *out = sign; - return; - } + if (value != value) + { + // Format NaN ourselves because sprintf's output is not consistent + // across platforms. + std::size_t size = 4; + const char *nan = upper ? " NAN" : " nan"; + if (!sign) + { + --size; + ++nan; + } + CharPtr out = write_str(nan, size, spec); + if (sign) + *out = sign; + return; + } - if (internal::isinfinity(value)) - { - // Format infinity ourselves because sprintf's output is not consistent - // across platforms. - std::size_t size = 4; - const char *inf = upper ? " INF" : " inf"; - if (!sign) - { - --size; - ++inf; - } - CharPtr out = write_str(inf, size, spec); - if (sign) - *out = sign; - return; - } + if (internal::isinfinity(value)) + { + // Format infinity ourselves because sprintf's output is not consistent + // across platforms. + std::size_t size = 4; + const char *inf = upper ? " INF" : " inf"; + if (!sign) + { + --size; + ++inf; + } + CharPtr out = write_str(inf, size, spec); + if (sign) + *out = sign; + return; + } - std::size_t offset = buffer_.size(); - unsigned width = spec.width(); - if (sign) - { - buffer_.reserve(buffer_.size() + (std::max)(width, 1u)); - if (width > 0) - --width; - ++offset; - } + std::size_t offset = buffer_.size(); + unsigned width = spec.width(); + if (sign) + { + buffer_.reserve(buffer_.size() + (std::max)(width, 1u)); + if (width > 0) + --width; + ++offset; + } - // Build format string. - enum { MAX_FORMAT_SIZE = 10 }; // longest format: %#-*.*Lg - Char format[MAX_FORMAT_SIZE]; - Char *format_ptr = format; - *format_ptr++ = '%'; - unsigned width_for_sprintf = width; - if (spec.flag(HASH_FLAG)) - *format_ptr++ = '#'; - if (spec.align() == ALIGN_CENTER) - { - width_for_sprintf = 0; - } - else - { - if (spec.align() == ALIGN_LEFT) - *format_ptr++ = '-'; - if (width != 0) - *format_ptr++ = '*'; - } - if (spec.precision() >= 0) - { - *format_ptr++ = '.'; - *format_ptr++ = '*'; - } - if (internal::IsLongDouble::VALUE) - *format_ptr++ = 'L'; - *format_ptr++ = type; - *format_ptr = '\0'; + // Build format string. + enum { MAX_FORMAT_SIZE = 10 }; // longest format: %#-*.*Lg + Char format[MAX_FORMAT_SIZE]; + Char *format_ptr = format; + *format_ptr++ = '%'; + unsigned width_for_sprintf = width; + if (spec.flag(HASH_FLAG)) + *format_ptr++ = '#'; + if (spec.align() == ALIGN_CENTER) + { + width_for_sprintf = 0; + } + else + { + if (spec.align() == ALIGN_LEFT) + *format_ptr++ = '-'; + if (width != 0) + *format_ptr++ = '*'; + } + if (spec.precision() >= 0) + { + *format_ptr++ = '.'; + *format_ptr++ = '*'; + } + if (internal::IsLongDouble::VALUE) + *format_ptr++ = 'L'; + *format_ptr++ = type; + *format_ptr = '\0'; - // Format using snprintf. - Char fill = static_cast(spec.fill()); - for (;;) - { - std::size_t size = buffer_.capacity() - offset; + // Format using snprintf. + Char fill = static_cast(spec.fill()); + for (;;) + { + std::size_t size = buffer_.capacity() - offset; #if _MSC_VER - // MSVC's vsnprintf_s doesn't work with zero size, so reserve - // space for at least one extra character to make the size non-zero. - // Note that the buffer's capacity will increase by more than 1. - if (size == 0) - { - buffer_.reserve(offset + 1); - size = buffer_.capacity() - offset; - } + // MSVC's vsnprintf_s doesn't work with zero size, so reserve + // space for at least one extra character to make the size non-zero. + // Note that the buffer's capacity will increase by more than 1. + if (size == 0) + { + buffer_.reserve(offset + 1); + size = buffer_.capacity() - offset; + } #endif - Char *start = &buffer_[offset]; - int n = internal::CharTraits::format_float( - start, size, format, width_for_sprintf, spec.precision(), value); - if (n >= 0 && offset + n < buffer_.capacity()) - { - if (sign) - { - if ((spec.align() != ALIGN_RIGHT && spec.align() != ALIGN_DEFAULT) || - *start != ' ') - { - *(start - 1) = sign; - sign = 0; - } - else - { - *(start - 1) = fill; - } - ++n; - } - if (spec.align() == ALIGN_CENTER && - spec.width() > static_cast(n)) - { - unsigned width = spec.width(); - CharPtr p = grow_buffer(width); - std::copy(p, p + n, p + (width - n) / 2); - fill_padding(p, spec.width(), n, fill); - return; - } - if (spec.fill() != ' ' || sign) - { - while (*start == ' ') - *start++ = fill; - if (sign) - *(start - 1) = sign; - } - grow_buffer(n); - return; - } - // If n is negative we ask to increase the capacity by at least 1, - // but as std::vector, the buffer grows exponentially. - buffer_.reserve(n >= 0 ? offset + n + 1 : buffer_.capacity() + 1); - } + Char *start = &buffer_[offset]; + int n = internal::CharTraits::format_float( + start, size, format, width_for_sprintf, spec.precision(), value); + if (n >= 0 && offset + n < buffer_.capacity()) + { + if (sign) + { + if ((spec.align() != ALIGN_RIGHT && spec.align() != ALIGN_DEFAULT) || + *start != ' ') + { + *(start - 1) = sign; + sign = 0; + } + else + { + *(start - 1) = fill; + } + ++n; + } + if (spec.align() == ALIGN_CENTER && + spec.width() > static_cast(n)) + { + unsigned width = spec.width(); + CharPtr p = grow_buffer(width); + std::copy(p, p + n, p + (width - n) / 2); + fill_padding(p, spec.width(), n, fill); + return; + } + if (spec.fill() != ' ' || sign) + { + while (*start == ' ') + *start++ = fill; + if (sign) + *(start - 1) = sign; + } + grow_buffer(n); + return; + } + // If n is negative we ask to increase the capacity by at least 1, + // but as std::vector, the buffer grows exponentially. + buffer_.reserve(n >= 0 ? offset + n + 1 : buffer_.capacity() + 1); + } } /** @@ -2419,30 +2419,30 @@ template > class BasicMemoryWriter : public BasicWriter { private: - internal::MemoryBuffer buffer_; + internal::MemoryBuffer buffer_; public: - explicit BasicMemoryWriter(const Allocator& alloc = Allocator()) - : BasicWriter(buffer_), buffer_(alloc) {} + explicit BasicMemoryWriter(const Allocator& alloc = Allocator()) + : BasicWriter(buffer_), buffer_(alloc) {} #if FMT_USE_RVALUE_REFERENCES - /** - Constructs a ``BasicMemoryWriter`` object moving the content of the other - object to it. - */ - BasicMemoryWriter(BasicMemoryWriter &&other) - : BasicWriter(buffer_), buffer_(std::move(other.buffer_)) - { - } + /** + Constructs a ``BasicMemoryWriter`` object moving the content of the other + object to it. + */ + BasicMemoryWriter(BasicMemoryWriter &&other) + : BasicWriter(buffer_), buffer_(std::move(other.buffer_)) + { + } - /** - Moves the content of the other ``BasicMemoryWriter`` object to this one. - */ - BasicMemoryWriter &operator=(BasicMemoryWriter &&other) - { - buffer_ = std::move(other.buffer_); - return *this; - } + /** + Moves the content of the other ``BasicMemoryWriter`` object to this one. + */ + BasicMemoryWriter &operator=(BasicMemoryWriter &&other) + { + buffer_ = std::move(other.buffer_); + return *this; + } #endif }; @@ -2453,14 +2453,14 @@ typedef BasicMemoryWriter WMemoryWriter; template void format(BasicFormatter &f, const Char *&format_str, const T &value) { - std::basic_ostringstream os; - os << value; - internal::Arg arg; - internal::Value &arg_value = arg; - std::basic_string str = os.str(); - arg_value = internal::MakeValue(str); - arg.type = internal::Arg::STRING; - format_str = f.format(format_str, arg); + std::basic_ostringstream os; + os << value; + internal::Arg arg; + internal::Value &arg_value = arg; + std::basic_string str = os.str(); + arg_value = internal::MakeValue(str); + arg.type = internal::Arg::STRING; + format_str = f.format(format_str, arg); } // Reports a system error without throwing an exception. @@ -2475,23 +2475,23 @@ A Windows error. class WindowsError : public SystemError { private: - void init(int error_code, StringRef format_str, ArgList args); + void init(int error_code, StringRef format_str, ArgList args); public: - /** - \rst - Constructs a :cpp:class:`fmt::WindowsError` object with the description - of the form "**: **", where ** is the - formatted message and ** is the system message corresponding - to the error code. - *error_code* is a Windows error code as given by ``GetLastError``. - \endrst - */ - WindowsError(int error_code, StringRef message) - { - init(error_code, message, ArgList()); - } - FMT_VARIADIC_CTOR(WindowsError, init, int, StringRef) + /** + \rst + Constructs a :cpp:class:`fmt::WindowsError` object with the description + of the form "**: **", where ** is the + formatted message and ** is the system message corresponding + to the error code. + *error_code* is a Windows error code as given by ``GetLastError``. + \endrst + */ + WindowsError(int error_code, StringRef message) + { + init(error_code, message, ArgList()); + } + FMT_VARIADIC_CTOR(WindowsError, init, int, StringRef) }; // Reports a Windows error without throwing an exception. @@ -2521,16 +2521,16 @@ std::string message = format("The answer is {}", 42); */ inline std::string format(StringRef format_str, ArgList args) { - MemoryWriter w; - w.write(format_str, args); - return w.str(); + MemoryWriter w; + w.write(format_str, args); + return w.str(); } inline std::wstring format(WStringRef format_str, ArgList args) { - WMemoryWriter w; - w.write(format_str, args); - return w.str(); + WMemoryWriter w; + w.write(format_str, args); + return w.str(); } /** @@ -2569,7 +2569,7 @@ void print(std::ostream &os, StringRef format_str, ArgList args); template void printf(BasicWriter &w, BasicStringRef format, ArgList args) { - internal::PrintfFormatter().format(w, format, args); + internal::PrintfFormatter().format(w, format, args); } /** @@ -2583,9 +2583,9 @@ std::string message = fmt::sprintf("The answer is %d", 42); */ inline std::string sprintf(StringRef format, ArgList args) { - MemoryWriter w; - printf(w, format, args); - return w.str(); + MemoryWriter w; + printf(w, format, args); + return w.str(); } /** @@ -2610,7 +2610,7 @@ fmt::printf("Elapsed time: %.2f seconds", 1.23); */ inline int printf(StringRef format, ArgList args) { - return fprintf(stdout, format, args); + return fprintf(stdout, format, args); } /** @@ -2619,99 +2619,99 @@ Fast integer formatter. class FormatInt { private: - // Buffer should be large enough to hold all digits (digits10 + 1), - // a sign and a null character. - enum { BUFFER_SIZE = std::numeric_limits::digits10 + 3 }; - mutable char buffer_[BUFFER_SIZE]; - char *str_; + // Buffer should be large enough to hold all digits (digits10 + 1), + // a sign and a null character. + enum { BUFFER_SIZE = std::numeric_limits::digits10 + 3 }; + mutable char buffer_[BUFFER_SIZE]; + char *str_; - // Formats value in reverse and returns the number of digits. - char *format_decimal(ULongLong value) - { - char *buffer_end = buffer_ + BUFFER_SIZE - 1; - while (value >= 100) - { - // Integer division is slow so do it for a group of two digits instead - // of for every digit. The idea comes from the talk by Alexandrescu - // "Three Optimization Tips for C++". See speed-test for a comparison. - unsigned index = (value % 100) * 2; - value /= 100; - *--buffer_end = internal::Data::DIGITS[index + 1]; - *--buffer_end = internal::Data::DIGITS[index]; - } - if (value < 10) - { - *--buffer_end = static_cast('0' + value); - return buffer_end; - } - unsigned index = static_cast(value * 2); - *--buffer_end = internal::Data::DIGITS[index + 1]; - *--buffer_end = internal::Data::DIGITS[index]; - return buffer_end; - } + // Formats value in reverse and returns the number of digits. + char *format_decimal(ULongLong value) + { + char *buffer_end = buffer_ + BUFFER_SIZE - 1; + while (value >= 100) + { + // Integer division is slow so do it for a group of two digits instead + // of for every digit. The idea comes from the talk by Alexandrescu + // "Three Optimization Tips for C++". See speed-test for a comparison. + unsigned index = (value % 100) * 2; + value /= 100; + *--buffer_end = internal::Data::DIGITS[index + 1]; + *--buffer_end = internal::Data::DIGITS[index]; + } + if (value < 10) + { + *--buffer_end = static_cast('0' + value); + return buffer_end; + } + unsigned index = static_cast(value * 2); + *--buffer_end = internal::Data::DIGITS[index + 1]; + *--buffer_end = internal::Data::DIGITS[index]; + return buffer_end; + } - void FormatSigned(LongLong value) - { - ULongLong abs_value = static_cast(value); - bool negative = value < 0; - if (negative) - abs_value = 0 - abs_value; - str_ = format_decimal(abs_value); - if (negative) - *--str_ = '-'; - } + void FormatSigned(LongLong value) + { + ULongLong abs_value = static_cast(value); + bool negative = value < 0; + if (negative) + abs_value = 0 - abs_value; + str_ = format_decimal(abs_value); + if (negative) + *--str_ = '-'; + } public: - explicit FormatInt(int value) - { - FormatSigned(value); - } - explicit FormatInt(long value) - { - FormatSigned(value); - } - explicit FormatInt(LongLong value) - { - FormatSigned(value); - } - explicit FormatInt(unsigned value) : str_(format_decimal(value)) {} - explicit FormatInt(unsigned long value) : str_(format_decimal(value)) {} - explicit FormatInt(ULongLong value) : str_(format_decimal(value)) {} + explicit FormatInt(int value) + { + FormatSigned(value); + } + explicit FormatInt(long value) + { + FormatSigned(value); + } + explicit FormatInt(LongLong value) + { + FormatSigned(value); + } + explicit FormatInt(unsigned value) : str_(format_decimal(value)) {} + explicit FormatInt(unsigned long value) : str_(format_decimal(value)) {} + explicit FormatInt(ULongLong value) : str_(format_decimal(value)) {} - /** - Returns the number of characters written to the output buffer. - */ - std::size_t size() const - { - return buffer_ - str_ + BUFFER_SIZE - 1; - } + /** + Returns the number of characters written to the output buffer. + */ + std::size_t size() const + { + return buffer_ - str_ + BUFFER_SIZE - 1; + } - /** - Returns a pointer to the output buffer content. No terminating null - character is appended. - */ - const char *data() const - { - return str_; - } + /** + Returns a pointer to the output buffer content. No terminating null + character is appended. + */ + const char *data() const + { + return str_; + } - /** - Returns a pointer to the output buffer content with terminating null - character appended. - */ - const char *c_str() const - { - buffer_[BUFFER_SIZE - 1] = '\0'; - return str_; - } + /** + Returns a pointer to the output buffer content with terminating null + character appended. + */ + const char *c_str() const + { + buffer_[BUFFER_SIZE - 1] = '\0'; + return str_; + } - /** - Returns the content of the output buffer as an `std::string`. - */ - std::string str() const - { - return std::string(str_, size()); - } + /** + Returns the content of the output buffer as an `std::string`. + */ + std::string str() const + { + return std::string(str_, size()); + } }; // Formats a decimal integer value writing into buffer and returns @@ -2720,27 +2720,27 @@ public: template inline void format_decimal(char *&buffer, T value) { - typename internal::IntTraits::MainType abs_value = value; - if (internal::is_negative(value)) - { - *buffer++ = '-'; - abs_value = 0 - abs_value; - } - if (abs_value < 100) - { - if (abs_value < 10) - { - *buffer++ = static_cast('0' + abs_value); - return; - } - unsigned index = static_cast(abs_value * 2); - *buffer++ = internal::Data::DIGITS[index]; - *buffer++ = internal::Data::DIGITS[index + 1]; - return; - } - unsigned num_digits = internal::count_digits(abs_value); - internal::format_decimal(buffer, abs_value, num_digits); - buffer += num_digits; + typename internal::IntTraits::MainType abs_value = value; + if (internal::is_negative(value)) + { + *buffer++ = '-'; + abs_value = 0 - abs_value; + } + if (abs_value < 100) + { + if (abs_value < 10) + { + *buffer++ = static_cast('0' + abs_value); + return; + } + unsigned index = static_cast(abs_value * 2); + *buffer++ = internal::Data::DIGITS[index]; + *buffer++ = internal::Data::DIGITS[index + 1]; + return; + } + unsigned num_digits = internal::count_digits(abs_value); + internal::format_decimal(buffer, abs_value, num_digits); + buffer += num_digits; } } // ns fmt } // ns deatils diff --git a/include/spdlog/details/line_logger.h b/include/spdlog/details/line_logger.h index 7160f6da..32dccf33 100644 --- a/include/spdlog/details/line_logger.h +++ b/include/spdlog/details/line_logger.h @@ -38,73 +38,73 @@ namespace details class line_logger { public: - line_logger(logger* callback_logger, level::level_enum msg_level, bool enabled): - _callback_logger(callback_logger), - _log_msg(msg_level), - _enabled(enabled) - {} + line_logger(logger* callback_logger, level::level_enum msg_level, bool enabled): + _callback_logger(callback_logger), + _log_msg(msg_level), + _enabled(enabled) + {} - // No copy intended. Only move - line_logger(const line_logger& other) = delete; - line_logger& operator=(const line_logger&) = delete; - line_logger& operator=(line_logger&&) = delete; + // No copy intended. Only move + line_logger(const line_logger& other) = delete; + line_logger& operator=(const line_logger&) = delete; + line_logger& operator=(line_logger&&) = delete; - line_logger(line_logger&& other) : - _callback_logger(other._callback_logger), - _log_msg(std::move(other._log_msg)), - _enabled(other._enabled) - { - other.disable(); - } + line_logger(line_logger&& other) : + _callback_logger(other._callback_logger), + _log_msg(std::move(other._log_msg)), + _enabled(other._enabled) + { + other.disable(); + } - //Log the log message using the callback logger - ~line_logger() - { - if (_enabled) - { - _log_msg.logger_name = _callback_logger->name(); - _log_msg.time = log_clock::now(); - _callback_logger->_log_msg(_log_msg); - } - } + //Log the log message using the callback logger + ~line_logger() + { + if (_enabled) + { + _log_msg.logger_name = _callback_logger->name(); + _log_msg.time = log_clock::now(); + _callback_logger->_log_msg(_log_msg); + } + } - template - void write(const char* fmt, const Args&... args) - { - if (!_enabled) - return; - try - { - _log_msg.raw.write(fmt, args...); - } - catch (const fmt::FormatError& e) - { - throw spdlog_ex(fmt::format("formatting error while processing format string '{}': {}", fmt, e.what())); - } - } + template + void write(const char* fmt, const Args&... args) + { + if (!_enabled) + return; + try + { + _log_msg.raw.write(fmt, args...); + } + catch (const fmt::FormatError& e) + { + throw spdlog_ex(fmt::format("formatting error while processing format string '{}': {}", fmt, e.what())); + } + } - template - line_logger& operator<<(const T& what) - { - if (_enabled) - _log_msg.raw << what; - return *this; - } + template + line_logger& operator<<(const T& what) + { + if (_enabled) + _log_msg.raw << what; + return *this; + } - void disable() - { - _enabled = false; - } + void disable() + { + _enabled = false; + } private: - logger* _callback_logger; - log_msg _log_msg; - bool _enabled; + logger* _callback_logger; + log_msg _log_msg; + bool _enabled; }; } //Namespace details } // Namespace spdlog diff --git a/include/spdlog/details/log_msg.h b/include/spdlog/details/log_msg.h index fcf5ca3c..d8654428 100644 --- a/include/spdlog/details/log_msg.h +++ b/include/spdlog/details/log_msg.h @@ -33,63 +33,62 @@ namespace details { struct log_msg { - log_msg() = default; - log_msg(level::level_enum l): - logger_name(), - level(l), - time(), - raw(), - formatted() {} + log_msg() = default; + log_msg(level::level_enum l): + logger_name(), + level(l), + time(), + raw(), + formatted() {} - log_msg(const log_msg& other) : - logger_name(other.logger_name), - level(other.level), - time(other.time) - { - if (other.raw.size()) - raw << fmt::BasicStringRef(other.raw.data(), other.raw.size()); - if (other.formatted.size()) - formatted << fmt::BasicStringRef(other.formatted.data(), other.formatted.size()); + log_msg(const log_msg& other) : + logger_name(other.logger_name), + level(other.level), + time(other.time) + { + if (other.raw.size()) + raw << fmt::BasicStringRef(other.raw.data(), other.raw.size()); + if (other.formatted.size()) + formatted << fmt::BasicStringRef(other.formatted.data(), other.formatted.size()); + } - } + log_msg(log_msg&& other) : + logger_name(std::move(other.logger_name)), + level(other.level), + time(std::move(other.time)), + raw(std::move(other.raw)), + formatted(std::move(other.formatted)) + { + other.clear(); + } - log_msg(log_msg&& other) : - logger_name(std::move(other.logger_name)), - level(other.level), - time(std::move(other.time)), - raw(std::move(other.raw)), - formatted(std::move(other.formatted)) - { - other.clear(); - } + log_msg& operator=(log_msg&& other) + { + if (this == &other) + return *this; - log_msg& operator=(log_msg&& other) - { - if (this == &other) - return *this; + logger_name = std::move(other.logger_name); + level = other.level; + time = std::move(other.time); + raw = std::move(other.raw); + formatted = std::move(other.formatted); + other.clear(); + return *this; + } - logger_name = std::move(other.logger_name); - level = other.level; - time = std::move(other.time); - raw = std::move(other.raw); - formatted = std::move(other.formatted); - other.clear(); - return *this; - } + void clear() + { + level = level::off; + raw.clear(); + formatted.clear(); + } - void clear() - { - level = level::off; - raw.clear(); - formatted.clear(); - } - - std::string logger_name; - level::level_enum level; - log_clock::time_point time; - fmt::MemoryWriter raw; - fmt::MemoryWriter formatted; + std::string logger_name; + level::level_enum level; + log_clock::time_point time; + fmt::MemoryWriter raw; + fmt::MemoryWriter formatted; }; } } diff --git a/include/spdlog/details/logger_impl.h b/include/spdlog/details/logger_impl.h index 3b680063..18a8fc16 100644 --- a/include/spdlog/details/logger_impl.h +++ b/include/spdlog/details/logger_impl.h @@ -34,23 +34,23 @@ // all other ctors will call this one template inline spdlog::logger::logger(const std::string& logger_name, const It& begin, const It& end) : - _name(logger_name), - _sinks(begin, end), - _formatter(std::make_shared("%+")) + _name(logger_name), + _sinks(begin, end), + _formatter(std::make_shared("%+")) { - // no support under vs2013 for member initialization for std::atomic - _level = level::info; + // no support under vs2013 for member initialization for std::atomic + _level = level::info; } // ctor with sinks as init list inline spdlog::logger::logger(const std::string& logger_name, sinks_init_list sinks_list) : - logger(logger_name, sinks_list.begin(), sinks_list.end()) {} + logger(logger_name, sinks_list.begin(), sinks_list.end()) {} // ctor with single sink inline spdlog::logger::logger(const std::string& logger_name, spdlog::sink_ptr single_sink) : - logger(logger_name, { single_sink }) {} + logger(logger_name, { single_sink }) {} inline spdlog::logger::~logger() = default; @@ -58,12 +58,12 @@ inline spdlog::logger::~logger() = default; inline void spdlog::logger::set_formatter(spdlog::formatter_ptr msg_formatter) { - _set_formatter(msg_formatter); + _set_formatter(msg_formatter); } inline void spdlog::logger::set_pattern(const std::string& pattern) { - _set_pattern(pattern); + _set_pattern(pattern); } // @@ -74,15 +74,15 @@ inline void spdlog::logger::set_pattern(const std::string& pattern) template inline spdlog::details::line_logger spdlog::logger::_log_if_enabled(level::level_enum lvl, const char* fmt, const Args&... args) { - bool msg_enabled = should_log(lvl); - details::line_logger l(this, lvl, msg_enabled); - l.write(fmt, args...); - return l; + bool msg_enabled = should_log(lvl); + details::line_logger l(this, lvl, msg_enabled); + l.write(fmt, args...); + return l; } inline spdlog::details::line_logger spdlog::logger::_log_if_enabled(level::level_enum lvl) { - return details::line_logger(this, lvl, should_log(lvl)); + return details::line_logger(this, lvl, should_log(lvl)); } @@ -92,55 +92,55 @@ inline spdlog::details::line_logger spdlog::logger::_log_if_enabled(level::level template inline spdlog::details::line_logger spdlog::logger::trace(const char* fmt, const Args&... args) { - return _log_if_enabled(level::trace, fmt, args...); + return _log_if_enabled(level::trace, fmt, args...); } template inline spdlog::details::line_logger spdlog::logger::debug(const char* fmt, const Args&... args) { - return _log_if_enabled(level::debug, fmt, args...); + return _log_if_enabled(level::debug, fmt, args...); } template inline spdlog::details::line_logger spdlog::logger::info(const char* fmt, const Args&... args) { - return _log_if_enabled(level::info, fmt, args...); + return _log_if_enabled(level::info, fmt, args...); } template inline spdlog::details::line_logger spdlog::logger::notice(const char* fmt, const Args&... args) { - return _log_if_enabled(level::notice, fmt, args...); + return _log_if_enabled(level::notice, fmt, args...); } template inline spdlog::details::line_logger spdlog::logger::warn(const char* fmt, const Args&... args) { - return _log_if_enabled(level::warn, fmt, args...); + return _log_if_enabled(level::warn, fmt, args...); } template inline spdlog::details::line_logger spdlog::logger::error(const char* fmt, const Args&... args) { - return _log_if_enabled(level::err, fmt, args...); + return _log_if_enabled(level::err, fmt, args...); } template inline spdlog::details::line_logger spdlog::logger::critical(const char* fmt, const Args&... args) { - return _log_if_enabled(level::critical, fmt, args...); + return _log_if_enabled(level::critical, fmt, args...); } template inline spdlog::details::line_logger spdlog::logger::alert(const char* fmt, const Args&... args) { - return _log_if_enabled(level::alert, fmt, args...); + return _log_if_enabled(level::alert, fmt, args...); } template inline spdlog::details::line_logger spdlog::logger::emerg(const char* fmt, const Args&... args) { - return _log_if_enabled(level::emerg, fmt, args...); + return _log_if_enabled(level::emerg, fmt, args...); } @@ -152,48 +152,48 @@ inline spdlog::details::line_logger spdlog::logger::emerg(const char* fmt, const inline spdlog::details::line_logger spdlog::logger::trace() { - return _log_if_enabled(level::trace); + return _log_if_enabled(level::trace); } inline spdlog::details::line_logger spdlog::logger::debug() { - return _log_if_enabled(level::debug); + return _log_if_enabled(level::debug); } inline spdlog::details::line_logger spdlog::logger::info() { - return _log_if_enabled(level::info); + return _log_if_enabled(level::info); } inline spdlog::details::line_logger spdlog::logger::notice() { - return _log_if_enabled(level::notice); + return _log_if_enabled(level::notice); } inline spdlog::details::line_logger spdlog::logger::warn() { - return _log_if_enabled(level::warn); + return _log_if_enabled(level::warn); } inline spdlog::details::line_logger spdlog::logger::error() { - return _log_if_enabled(level::err); + return _log_if_enabled(level::err); } inline spdlog::details::line_logger spdlog::logger::critical() { - return _log_if_enabled(level::critical); + return _log_if_enabled(level::critical); } inline spdlog::details::line_logger spdlog::logger::alert() { - return _log_if_enabled(level::alert); + return _log_if_enabled(level::alert); } inline spdlog::details::line_logger spdlog::logger::emerg() { - return _log_if_enabled(level::emerg); + return _log_if_enabled(level::emerg); } @@ -201,9 +201,9 @@ inline spdlog::details::line_logger spdlog::logger::emerg() template inline spdlog::details::line_logger spdlog::logger::force_log(level::level_enum lvl, const char* fmt, const Args&... args) { - details::line_logger l(this, lvl, true); - l.write(fmt, args...); - return l; + details::line_logger l(this, lvl, true); + l.write(fmt, args...); + return l; } // @@ -211,27 +211,27 @@ inline spdlog::details::line_logger spdlog::logger::force_log(level::level_enum // inline const std::string& spdlog::logger::name() const { - return _name; + return _name; } inline void spdlog::logger::set_level(spdlog::level::level_enum log_level) { - _level.store(log_level); + _level.store(log_level); } inline spdlog::level::level_enum spdlog::logger::level() const { - return static_cast(_level.load()); + return static_cast(_level.load()); } inline bool spdlog::logger::should_log(spdlog::level::level_enum msg_level) const { - return msg_level >= _level.load(); + return msg_level >= _level.load(); } inline void spdlog::logger::stop() { - _stop(); + _stop(); } // @@ -239,23 +239,23 @@ inline void spdlog::logger::stop() // inline void spdlog::logger::_log_msg(details::log_msg& msg) { - _formatter->format(msg); - for (auto &sink : _sinks) - sink->log(msg); + _formatter->format(msg); + for (auto &sink : _sinks) + sink->log(msg); } inline void spdlog::logger::_set_pattern(const std::string& pattern) { - _formatter = std::make_shared(pattern); + _formatter = std::make_shared(pattern); } inline void spdlog::logger::_set_formatter(formatter_ptr msg_formatter) { - _formatter = msg_formatter; + _formatter = msg_formatter; } inline void spdlog::logger::_stop() { - set_level(level::off); + set_level(level::off); } diff --git a/include/spdlog/details/mpmc_bounded_q.h b/include/spdlog/details/mpmc_bounded_q.h index 7cbcfd70..e567c66c 100644 --- a/include/spdlog/details/mpmc_bounded_q.h +++ b/include/spdlog/details/mpmc_bounded_q.h @@ -74,101 +74,101 @@ class mpmc_bounded_queue { public: - using item_type = T; - mpmc_bounded_queue(size_t buffer_size) - : buffer_(new cell_t [buffer_size]), - buffer_mask_(buffer_size - 1) - { - //queue size must be power of two - if(!((buffer_size >= 2) && ((buffer_size & (buffer_size - 1)) == 0))) - throw spdlog_ex("async logger queue size must be power of two"); + using item_type = T; + mpmc_bounded_queue(size_t buffer_size) + : buffer_(new cell_t [buffer_size]), + buffer_mask_(buffer_size - 1) + { + //queue size must be power of two + if(!((buffer_size >= 2) && ((buffer_size & (buffer_size - 1)) == 0))) + throw spdlog_ex("async logger queue size must be power of two"); - for (size_t i = 0; i != buffer_size; i += 1) - buffer_[i].sequence_.store(i, std::memory_order_relaxed); - enqueue_pos_.store(0, std::memory_order_relaxed); - dequeue_pos_.store(0, std::memory_order_relaxed); - } + for (size_t i = 0; i != buffer_size; i += 1) + buffer_[i].sequence_.store(i, std::memory_order_relaxed); + enqueue_pos_.store(0, std::memory_order_relaxed); + dequeue_pos_.store(0, std::memory_order_relaxed); + } - ~mpmc_bounded_queue() - { - delete [] buffer_; - } + ~mpmc_bounded_queue() + { + delete [] buffer_; + } - bool enqueue(T&& data) - { - cell_t* cell; - size_t pos = enqueue_pos_.load(std::memory_order_relaxed); - for (;;) - { - cell = &buffer_[pos & buffer_mask_]; - size_t seq = cell->sequence_.load(std::memory_order_acquire); - intptr_t dif = (intptr_t)seq - (intptr_t)pos; - if (dif == 0) - { - if (enqueue_pos_.compare_exchange_weak(pos, pos + 1, std::memory_order_relaxed)) - break; - } - else if (dif < 0) - { - return false; - } - else - { - pos = enqueue_pos_.load(std::memory_order_relaxed); - } - } - cell->data_ = std::move(data); - cell->sequence_.store(pos + 1, std::memory_order_release); - return true; - } + bool enqueue(T&& data) + { + cell_t* cell; + size_t pos = enqueue_pos_.load(std::memory_order_relaxed); + for (;;) + { + cell = &buffer_[pos & buffer_mask_]; + size_t seq = cell->sequence_.load(std::memory_order_acquire); + intptr_t dif = (intptr_t)seq - (intptr_t)pos; + if (dif == 0) + { + if (enqueue_pos_.compare_exchange_weak(pos, pos + 1, std::memory_order_relaxed)) + break; + } + else if (dif < 0) + { + return false; + } + else + { + pos = enqueue_pos_.load(std::memory_order_relaxed); + } + } + cell->data_ = std::move(data); + cell->sequence_.store(pos + 1, std::memory_order_release); + return true; + } - bool dequeue(T& data) - { - cell_t* cell; - size_t pos = dequeue_pos_.load(std::memory_order_relaxed); - for (;;) - { - cell = &buffer_[pos & buffer_mask_]; - size_t seq = - cell->sequence_.load(std::memory_order_acquire); - intptr_t dif = (intptr_t)seq - (intptr_t)(pos + 1); - if (dif == 0) - { - if (dequeue_pos_.compare_exchange_weak(pos, pos + 1, std::memory_order_relaxed)) - break; - } - else if (dif < 0) - return false; - else - pos = dequeue_pos_.load(std::memory_order_relaxed); - } - data = std::move(cell->data_); - cell->sequence_.store(pos + buffer_mask_ + 1, std::memory_order_release); - return true; - } + bool dequeue(T& data) + { + cell_t* cell; + size_t pos = dequeue_pos_.load(std::memory_order_relaxed); + for (;;) + { + cell = &buffer_[pos & buffer_mask_]; + size_t seq = + cell->sequence_.load(std::memory_order_acquire); + intptr_t dif = (intptr_t)seq - (intptr_t)(pos + 1); + if (dif == 0) + { + if (dequeue_pos_.compare_exchange_weak(pos, pos + 1, std::memory_order_relaxed)) + break; + } + else if (dif < 0) + return false; + else + pos = dequeue_pos_.load(std::memory_order_relaxed); + } + data = std::move(cell->data_); + cell->sequence_.store(pos + buffer_mask_ + 1, std::memory_order_release); + return true; + } private: - struct cell_t - { - std::atomic sequence_; - T data_; - }; + struct cell_t + { + std::atomic sequence_; + T data_; + }; - static size_t const cacheline_size = 64; - typedef char cacheline_pad_t [cacheline_size]; + static size_t const cacheline_size = 64; + typedef char cacheline_pad_t [cacheline_size]; - cacheline_pad_t pad0_; - cell_t* const buffer_; - size_t const buffer_mask_; - cacheline_pad_t pad1_; - std::atomic enqueue_pos_; - cacheline_pad_t pad2_; - std::atomic dequeue_pos_; - cacheline_pad_t pad3_; + cacheline_pad_t pad0_; + cell_t* const buffer_; + size_t const buffer_mask_; + cacheline_pad_t pad1_; + std::atomic enqueue_pos_; + cacheline_pad_t pad2_; + std::atomic dequeue_pos_; + cacheline_pad_t pad3_; - mpmc_bounded_queue(mpmc_bounded_queue const&); - void operator = (mpmc_bounded_queue const&); + mpmc_bounded_queue(mpmc_bounded_queue const&); + void operator = (mpmc_bounded_queue const&); }; } // ns details diff --git a/include/spdlog/details/null_mutex.h b/include/spdlog/details/null_mutex.h index ebb56a59..9063bfd5 100644 --- a/include/spdlog/details/null_mutex.h +++ b/include/spdlog/details/null_mutex.h @@ -32,12 +32,12 @@ namespace details { struct null_mutex { - void lock() {} - void unlock() {} - bool try_lock() - { - return true; - } + void lock() {} + void unlock() {} + bool try_lock() + { + return true; + } }; } } diff --git a/include/spdlog/details/os.h b/include/spdlog/details/os.h index f67cad29..f5840bfd 100644 --- a/include/spdlog/details/os.h +++ b/include/spdlog/details/os.h @@ -31,7 +31,7 @@ #ifdef _WIN32 #define WIN32_LEAN_AND_MEAN #include -#endif +#endif namespace spdlog { @@ -44,19 +44,19 @@ inline std::tm localtime(const std::time_t &time_tt) { #ifdef _WIN32 - std::tm tm; - localtime_s(&tm, &time_tt); + std::tm tm; + localtime_s(&tm, &time_tt); #else - std::tm tm; - localtime_r(&time_tt, &tm); + std::tm tm; + localtime_r(&time_tt, &tm); #endif - return tm; + return tm; } inline std::tm localtime() { - std::time_t now_t = time(0); - return localtime(now_t); + std::time_t now_t = time(0); + return localtime(now_t); } @@ -64,57 +64,57 @@ inline std::tm gmtime(const std::time_t &time_tt) { #ifdef _WIN32 - std::tm tm; - gmtime_s(&tm, &time_tt); + std::tm tm; + gmtime_s(&tm, &time_tt); #else - std::tm tm; - gmtime_r(&time_tt, &tm); + std::tm tm; + gmtime_r(&time_tt, &tm); #endif - return tm; + return tm; } inline std::tm gmtime() { - std::time_t now_t = time(0); - return gmtime(now_t); + std::time_t now_t = time(0); + return gmtime(now_t); } inline bool operator==(const std::tm& tm1, const std::tm& tm2) { - return (tm1.tm_sec == tm2.tm_sec && - tm1.tm_min == tm2.tm_min && - tm1.tm_hour == tm2.tm_hour && - tm1.tm_mday == tm2.tm_mday && - tm1.tm_mon == tm2.tm_mon && - tm1.tm_year == tm2.tm_year && - tm1.tm_isdst == tm2.tm_isdst); + return (tm1.tm_sec == tm2.tm_sec && + tm1.tm_min == tm2.tm_min && + tm1.tm_hour == tm2.tm_hour && + tm1.tm_mday == tm2.tm_mday && + tm1.tm_mon == tm2.tm_mon && + tm1.tm_year == tm2.tm_year && + tm1.tm_isdst == tm2.tm_isdst); } inline bool operator!=(const std::tm& tm1, const std::tm& tm2) { - return !(tm1 == tm2); + return !(tm1 == tm2); } #ifdef _WIN32 inline const char* eol() { - return "\r\n"; + return "\r\n"; } #else constexpr inline const char* eol() { - return "\n"; + return "\n"; } #endif #ifdef _WIN32 inline unsigned short eol_size() { - return 2; + return 2; } #else constexpr inline unsigned short eol_size() { - return 1; + return 1; } #endif @@ -122,11 +122,11 @@ constexpr inline unsigned short eol_size() inline int fopen_s(FILE** fp, const std::string& filename, const char* mode) { #ifdef _WIN32 - *fp = _fsopen((filename.c_str()), mode, _SH_DENYWR); - return *fp == nullptr; + *fp = _fsopen((filename.c_str()), mode, _SH_DENYWR); + return *fp == nullptr; #else - *fp = fopen((filename.c_str()), mode); - return *fp == nullptr; + *fp = fopen((filename.c_str()), mode); + return *fp == nullptr; #endif @@ -137,14 +137,14 @@ inline int utc_minutes_offset(const std::tm& tm = details::os::localtime()) { #ifdef _WIN32 - (void)tm; // avoid unused param warning - DYNAMIC_TIME_ZONE_INFORMATION tzinfo; - auto rv = GetDynamicTimeZoneInformation(&tzinfo); - if (!rv) - return -1; - return -1 * (tzinfo.Bias + tzinfo.DaylightBias); + (void)tm; // avoid unused param warning + DYNAMIC_TIME_ZONE_INFORMATION tzinfo; + auto rv = GetDynamicTimeZoneInformation(&tzinfo); + if (!rv) + return -1; + return -1 * (tzinfo.Bias + tzinfo.DaylightBias); #else - return static_cast(tm.tm_gmtoff / 60); + return static_cast(tm.tm_gmtoff / 60); #endif } diff --git a/include/spdlog/details/pattern_formatter_impl.h b/include/spdlog/details/pattern_formatter_impl.h index 7c44dd7f..3d301624 100644 --- a/include/spdlog/details/pattern_formatter_impl.h +++ b/include/spdlog/details/pattern_formatter_impl.h @@ -42,8 +42,8 @@ namespace details class flag_formatter { public: - virtual ~flag_formatter() {} - virtual void format(details::log_msg& msg, const std::tm& tm_time) = 0; + virtual ~flag_formatter() {} + virtual void format(details::log_msg& msg, const std::tm& tm_time) = 0; }; /////////////////////////////////////////////////////////////////////// @@ -53,20 +53,20 @@ namespace { class name_formatter :public flag_formatter { - void format(details::log_msg& msg, const std::tm&) override - { - msg.formatted << msg.logger_name; - } + void format(details::log_msg& msg, const std::tm&) override + { + msg.formatted << msg.logger_name; + } }; } // log level appender class level_formatter :public flag_formatter { - void format(details::log_msg& msg, const std::tm&) override - { - msg.formatted << level::to_str(msg.level); - } + void format(details::log_msg& msg, const std::tm&) override + { + msg.formatted << level::to_str(msg.level); + } }; /////////////////////////////////////////////////////////////////////// @@ -75,88 +75,88 @@ class level_formatter :public flag_formatter static const char* ampm(const tm& t) { - return t.tm_hour >= 12 ? "PM" : "AM"; + return t.tm_hour >= 12 ? "PM" : "AM"; } static int to12h(const tm& t) { - return t.tm_hour > 12 ? t.tm_hour - 12 : t.tm_hour; + return t.tm_hour > 12 ? t.tm_hour - 12 : t.tm_hour; } //Abbreviated weekday name static const std::string days[] { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; class a_formatter :public flag_formatter { - void format(details::log_msg& msg, const std::tm& tm_time) override - { - msg.formatted << days[tm_time.tm_wday]; - } + void format(details::log_msg& msg, const std::tm& tm_time) override + { + msg.formatted << days[tm_time.tm_wday]; + } }; //Full weekday name static const std::string full_days[] { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" }; class A_formatter :public flag_formatter { - void format(details::log_msg& msg, const std::tm& tm_time) override - { - msg.formatted << full_days[tm_time.tm_wday]; - } + void format(details::log_msg& msg, const std::tm& tm_time) override + { + msg.formatted << full_days[tm_time.tm_wday]; + } }; //Abbreviated month static const std::string months[] { "Jan", "Feb", "Mar", "Apr", "May", "June", "July", "Aug", "Sept", "Oct", "Nov", "Dec" }; class b_formatter :public flag_formatter { - void format(details::log_msg& msg, const std::tm& tm_time) override - { - msg.formatted<< months[tm_time.tm_mon]; - } + void format(details::log_msg& msg, const std::tm& tm_time) override + { + msg.formatted<< months[tm_time.tm_mon]; + } }; //Full month name static const std::string full_months[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; class B_formatter :public flag_formatter { - void format(details::log_msg& msg, const std::tm& tm_time) override - { - msg.formatted << full_months[tm_time.tm_mon]; - } + void format(details::log_msg& msg, const std::tm& tm_time) override + { + msg.formatted << full_months[tm_time.tm_mon]; + } }; //write 2 ints seperated by sep with padding of 2 static fmt::MemoryWriter& pad_n_join(fmt::MemoryWriter& w, int v1, int v2, char sep) { - w << fmt::pad(v1, 2, '0') << sep << fmt::pad(v2, 2, '0'); - return w; + w << fmt::pad(v1, 2, '0') << sep << fmt::pad(v2, 2, '0'); + return w; } //write 3 ints seperated by sep with padding of 2 static fmt::MemoryWriter& pad_n_join(fmt::MemoryWriter& w, int v1, int v2, int v3, char sep) { - w << fmt::pad(v1, 2, '0') << sep << fmt::pad(v2, 2, '0') << sep << fmt::pad(v3, 2, '0'); - return w; + w << fmt::pad(v1, 2, '0') << sep << fmt::pad(v2, 2, '0') << sep << fmt::pad(v3, 2, '0'); + return w; } //Date and time representation (Thu Aug 23 15:35:46 2014) class c_formatter :public flag_formatter { - void format(details::log_msg& msg, const std::tm& tm_time) override - { - msg.formatted << days[tm_time.tm_wday] << ' ' << months[tm_time.tm_mon] << ' ' << tm_time.tm_mday << ' '; - pad_n_join(msg.formatted, tm_time.tm_hour, tm_time.tm_min, tm_time.tm_sec, ':') << ' ' << tm_time.tm_year + 1900; - } + void format(details::log_msg& msg, const std::tm& tm_time) override + { + msg.formatted << days[tm_time.tm_wday] << ' ' << months[tm_time.tm_mon] << ' ' << tm_time.tm_mday << ' '; + pad_n_join(msg.formatted, tm_time.tm_hour, tm_time.tm_min, tm_time.tm_sec, ':') << ' ' << tm_time.tm_year + 1900; + } }; // year - 2 digit class C_formatter :public flag_formatter { - void format(details::log_msg& msg, const std::tm& tm_time) override - { - msg.formatted << fmt::pad(tm_time.tm_year % 100, 2, '0'); - } + void format(details::log_msg& msg, const std::tm& tm_time) override + { + msg.formatted << fmt::pad(tm_time.tm_year % 100, 2, '0'); + } }; @@ -164,122 +164,122 @@ class C_formatter :public flag_formatter // Short MM/DD/YY date, equivalent to %m/%d/%y 08/23/01 class D_formatter :public flag_formatter { - void format(details::log_msg& msg, const std::tm& tm_time) override - { - pad_n_join(msg.formatted, tm_time.tm_mon + 1, tm_time.tm_mday, tm_time.tm_year % 100, '/'); - } + void format(details::log_msg& msg, const std::tm& tm_time) override + { + pad_n_join(msg.formatted, tm_time.tm_mon + 1, tm_time.tm_mday, tm_time.tm_year % 100, '/'); + } }; // year - 4 digit class Y_formatter :public flag_formatter { - void format(details::log_msg& msg, const std::tm& tm_time) override - { - msg.formatted << tm_time.tm_year + 1900; - } + void format(details::log_msg& msg, const std::tm& tm_time) override + { + msg.formatted << tm_time.tm_year + 1900; + } }; // month 1-12 class m_formatter :public flag_formatter { - void format(details::log_msg& msg, const std::tm& tm_time) override - { - msg.formatted << fmt::pad(tm_time.tm_mon + 1, 2, '0'); - } + void format(details::log_msg& msg, const std::tm& tm_time) override + { + msg.formatted << fmt::pad(tm_time.tm_mon + 1, 2, '0'); + } }; // day of month 1-31 class d_formatter :public flag_formatter { - void format(details::log_msg& msg, const std::tm& tm_time) override - { - msg.formatted << fmt::pad(tm_time.tm_mday, 2, '0'); - } + void format(details::log_msg& msg, const std::tm& tm_time) override + { + msg.formatted << fmt::pad(tm_time.tm_mday, 2, '0'); + } }; // hours in 24 format 0-23 class H_formatter :public flag_formatter { - void format(details::log_msg& msg, const std::tm& tm_time) override - { - msg.formatted << fmt::pad(tm_time.tm_hour, 2, '0'); - } + void format(details::log_msg& msg, const std::tm& tm_time) override + { + msg.formatted << fmt::pad(tm_time.tm_hour, 2, '0'); + } }; // hours in 12 format 1-12 class I_formatter :public flag_formatter { - void format(details::log_msg& msg, const std::tm& tm_time) override - { - msg.formatted << fmt::pad(to12h(tm_time), 2, '0'); - } + void format(details::log_msg& msg, const std::tm& tm_time) override + { + msg.formatted << fmt::pad(to12h(tm_time), 2, '0'); + } }; // ninutes 0-59 class M_formatter :public flag_formatter { - void format(details::log_msg& msg, const std::tm& tm_time) override - { - msg.formatted << fmt::pad(tm_time.tm_min, 2, '0'); - } + void format(details::log_msg& msg, const std::tm& tm_time) override + { + msg.formatted << fmt::pad(tm_time.tm_min, 2, '0'); + } }; // seconds 0-59 class S_formatter :public flag_formatter { - void format(details::log_msg& msg, const std::tm& tm_time) override - { - msg.formatted << fmt::pad(tm_time.tm_sec, 2, '0'); - } + void format(details::log_msg& msg, const std::tm& tm_time) override + { + msg.formatted << fmt::pad(tm_time.tm_sec, 2, '0'); + } }; // milliseconds class e_formatter :public flag_formatter { - void format(details::log_msg& msg, const std::tm&) override - { - auto duration = msg.time.time_since_epoch(); - auto millis = std::chrono::duration_cast(duration).count() % 1000; - msg.formatted << fmt::pad(static_cast(millis), 3, '0'); - } + void format(details::log_msg& msg, const std::tm&) override + { + auto duration = msg.time.time_since_epoch(); + auto millis = std::chrono::duration_cast(duration).count() % 1000; + msg.formatted << fmt::pad(static_cast(millis), 3, '0'); + } }; // AM/PM class p_formatter :public flag_formatter { - void format(details::log_msg& msg, const std::tm& tm_time) override - { - msg.formatted << ampm(tm_time); - } + void format(details::log_msg& msg, const std::tm& tm_time) override + { + msg.formatted << ampm(tm_time); + } }; // 12 hour clock 02:55:02 pm class r_formatter :public flag_formatter { - void format(details::log_msg& msg, const std::tm& tm_time) override - { - pad_n_join(msg.formatted, to12h(tm_time), tm_time.tm_min, tm_time.tm_sec, ':') << ' ' << ampm(tm_time); - } + void format(details::log_msg& msg, const std::tm& tm_time) override + { + pad_n_join(msg.formatted, to12h(tm_time), tm_time.tm_min, tm_time.tm_sec, ':') << ' ' << ampm(tm_time); + } }; // 24-hour HH:MM time, equivalent to %H:%M class R_formatter :public flag_formatter { - void format(details::log_msg& msg, const std::tm& tm_time) override - { - pad_n_join(msg.formatted, tm_time.tm_hour, tm_time.tm_min, ':'); - } + void format(details::log_msg& msg, const std::tm& tm_time) override + { + pad_n_join(msg.formatted, tm_time.tm_hour, tm_time.tm_min, ':'); + } }; // ISO 8601 time format (HH:MM:SS), equivalent to %H:%M:%S class T_formatter :public flag_formatter { - void format(details::log_msg& msg, const std::tm& tm_time) override - { - pad_n_join(msg.formatted, tm_time.tm_hour, tm_time.tm_min, tm_time.tm_sec, ':'); - } + void format(details::log_msg& msg, const std::tm& tm_time) override + { + pad_n_join(msg.formatted, tm_time.tm_hour, tm_time.tm_min, tm_time.tm_sec, ':'); + } }; @@ -287,44 +287,44 @@ class T_formatter :public flag_formatter class z_formatter :public flag_formatter { public: - const std::chrono::seconds cache_refresh = std::chrono::seconds(5); + const std::chrono::seconds cache_refresh = std::chrono::seconds(5); - z_formatter() :_last_update(std::chrono::seconds(0)) {} - z_formatter(const z_formatter&) = delete; - z_formatter& operator=(const z_formatter&) = delete; + z_formatter() :_last_update(std::chrono::seconds(0)) {} + z_formatter(const z_formatter&) = delete; + z_formatter& operator=(const z_formatter&) = delete; - void format(details::log_msg& msg, const std::tm& tm_time) override - { + void format(details::log_msg& msg, const std::tm& tm_time) override + { #ifdef _WIN32 - int total_minutes = get_cached_offset(msg, tm_time); + int total_minutes = get_cached_offset(msg, tm_time); #else - // No need to chache under gcc, - // it is very fast (already stored in tm.tm_gmtoff) - int total_minutes = os::utc_minutes_offset(tm_time); + // No need to chache under gcc, + // it is very fast (already stored in tm.tm_gmtoff) + int total_minutes = os::utc_minutes_offset(tm_time); #endif - int h = total_minutes / 60; - int m = total_minutes % 60; - char sign = h >= 0 ? '+' : '-'; - msg.formatted << sign; - pad_n_join(msg.formatted, h, m, ':'); - } + int h = total_minutes / 60; + int m = total_minutes % 60; + char sign = h >= 0 ? '+' : '-'; + msg.formatted << sign; + pad_n_join(msg.formatted, h, m, ':'); + } private: - log_clock::time_point _last_update; - int _offset_minutes; - std::mutex _mutex; + log_clock::time_point _last_update; + int _offset_minutes; + std::mutex _mutex; - int get_cached_offset(const log_msg& msg, const std::tm& tm_time) - { - using namespace std::chrono; - std::lock_guard l(_mutex); - if (msg.time - _last_update >= cache_refresh) - { - _offset_minutes = os::utc_minutes_offset(tm_time); - _last_update = msg.time; - } - return _offset_minutes; - } + int get_cached_offset(const log_msg& msg, const std::tm& tm_time) + { + using namespace std::chrono; + std::lock_guard l(_mutex); + if (msg.time - _last_update >= cache_refresh) + { + _offset_minutes = os::utc_minutes_offset(tm_time); + _last_update = msg.time; + } + return _offset_minutes; + } }; @@ -332,32 +332,32 @@ private: //Thread id class t_formatter :public flag_formatter { - void format(details::log_msg& msg, const std::tm&) override - { - msg.formatted << std::hash()(std::this_thread::get_id()); - } + void format(details::log_msg& msg, const std::tm&) override + { + msg.formatted << std::hash()(std::this_thread::get_id()); + } }; class v_formatter :public flag_formatter { - void format(details::log_msg& msg, const std::tm&) override - { - msg.formatted << fmt::StringRef(msg.raw.data(), msg.raw.size()); - } + void format(details::log_msg& msg, const std::tm&) override + { + msg.formatted << fmt::StringRef(msg.raw.data(), msg.raw.size()); + } }; class ch_formatter :public flag_formatter { public: - explicit ch_formatter(char ch) : _ch(ch) - {} - void format(details::log_msg& msg, const std::tm&) override - { - msg.formatted << _ch; - } + explicit ch_formatter(char ch) : _ch(ch) + {} + void format(details::log_msg& msg, const std::tm&) override + { + msg.formatted << _ch; + } private: - char _ch; + char _ch; }; @@ -365,54 +365,54 @@ private: class aggregate_formatter :public flag_formatter { public: - aggregate_formatter() - {} - void add_ch(char ch) - { - _str += ch; - } - void format(details::log_msg& msg, const std::tm&) override - { - msg.formatted << _str; - } + aggregate_formatter() + {} + void add_ch(char ch) + { + _str += ch; + } + void format(details::log_msg& msg, const std::tm&) override + { + msg.formatted << _str; + } private: - std::string _str; + std::string _str; }; // Full info formatter // pattern: [%Y-%m-%d %H:%M:%S.%e] [%n] [%l] %v class full_formatter :public flag_formatter { - void format(details::log_msg& msg, const std::tm& tm_time) override - { - auto duration = msg.time.time_since_epoch(); - auto millis = std::chrono::duration_cast(duration).count() % 1000; + void format(details::log_msg& msg, const std::tm& tm_time) override + { + auto duration = msg.time.time_since_epoch(); + auto millis = std::chrono::duration_cast(duration).count() % 1000; - /* Slower version(while still very fast - about 3.2 million lines/sec under 10 threads), - msg.formatted.write("[{:d}-{:02d}-{:02d} {:02d}:{:02d}:{:02d}.{:03d}] [{}] [{}] {} ", - tm_time.tm_year + 1900, - tm_time.tm_mon + 1, - tm_time.tm_mday, - tm_time.tm_hour, - tm_time.tm_min, - tm_time.tm_sec, - static_cast(millis), - msg.logger_name, - level::to_str(msg.level), - msg.raw.str());*/ + /* Slower version(while still very fast - about 3.2 million lines/sec under 10 threads), + msg.formatted.write("[{:d}-{:02d}-{:02d} {:02d}:{:02d}:{:02d}.{:03d}] [{}] [{}] {} ", + tm_time.tm_year + 1900, + tm_time.tm_mon + 1, + tm_time.tm_mday, + tm_time.tm_hour, + tm_time.tm_min, + tm_time.tm_sec, + static_cast(millis), + msg.logger_name, + level::to_str(msg.level), + msg.raw.str());*/ - // Faster (albeit uglier) way to format the line (5.6 million lines/sec under 10 threads) - msg.formatted << '[' << static_cast(tm_time.tm_year + 1900) << '-' - << fmt::pad(static_cast(tm_time.tm_mon + 1), 2, '0') << '-' - << fmt::pad(static_cast(tm_time.tm_mday), 2, '0') << ' ' - << fmt::pad(static_cast(tm_time.tm_hour), 2, '0') << ':' - << fmt::pad(static_cast(tm_time.tm_min), 2, '0') << ':' - << fmt::pad(static_cast(tm_time.tm_sec), 2, '0') << '.' - << fmt::pad(static_cast(millis), 3, '0') << "] "; + // Faster (albeit uglier) way to format the line (5.6 million lines/sec under 10 threads) + msg.formatted << '[' << static_cast(tm_time.tm_year + 1900) << '-' + << fmt::pad(static_cast(tm_time.tm_mon + 1), 2, '0') << '-' + << fmt::pad(static_cast(tm_time.tm_mday), 2, '0') << ' ' + << fmt::pad(static_cast(tm_time.tm_hour), 2, '0') << ':' + << fmt::pad(static_cast(tm_time.tm_min), 2, '0') << ':' + << fmt::pad(static_cast(tm_time.tm_sec), 2, '0') << '.' + << fmt::pad(static_cast(millis), 3, '0') << "] "; - msg.formatted << '[' << msg.logger_name << "] [" << level::to_str(msg.level) << "] "; - msg.formatted << fmt::StringRef(msg.raw.data(), msg.raw.size()); - } + msg.formatted << '[' << msg.logger_name << "] [" << level::to_str(msg.level) << "] "; + msg.formatted << fmt::StringRef(msg.raw.data(), msg.raw.size()); + } }; } @@ -422,168 +422,168 @@ class full_formatter :public flag_formatter /////////////////////////////////////////////////////////////////////////////// inline spdlog::pattern_formatter::pattern_formatter(const std::string& pattern) { - compile_pattern(pattern); + compile_pattern(pattern); } inline void spdlog::pattern_formatter::compile_pattern(const std::string& pattern) { - auto end = pattern.end(); - std::unique_ptr user_chars; - for (auto it = pattern.begin(); it != end; ++it) - { - if (*it == '%') - { - if (user_chars) //append user chars found so far - _formatters.push_back(std::move(user_chars)); + auto end = pattern.end(); + std::unique_ptr user_chars; + for (auto it = pattern.begin(); it != end; ++it) + { + if (*it == '%') + { + if (user_chars) //append user chars found so far + _formatters.push_back(std::move(user_chars)); - if (++it != end) - handle_flag(*it); - else - break; - } - else // chars not following the % sign should be displayed as is - { - if (!user_chars) - user_chars = std::unique_ptr(new details::aggregate_formatter()); - user_chars->add_ch(*it); - } - } - if (user_chars) //append raw chars found so far - { - _formatters.push_back(std::move(user_chars)); - } + if (++it != end) + handle_flag(*it); + else + break; + } + else // chars not following the % sign should be displayed as is + { + if (!user_chars) + user_chars = std::unique_ptr(new details::aggregate_formatter()); + user_chars->add_ch(*it); + } + } + if (user_chars) //append raw chars found so far + { + _formatters.push_back(std::move(user_chars)); + } } inline void spdlog::pattern_formatter::handle_flag(char flag) { - switch (flag) - { - // logger name - case 'n': - _formatters.push_back(std::unique_ptr(new details::name_formatter())); - break; + switch (flag) + { + // logger name + case 'n': + _formatters.push_back(std::unique_ptr(new details::name_formatter())); + break; - case 'l': - _formatters.push_back(std::unique_ptr(new details::level_formatter())); - break; + case 'l': + _formatters.push_back(std::unique_ptr(new details::level_formatter())); + break; - case('t') : - _formatters.push_back(std::unique_ptr(new details::t_formatter())); - break; + case('t') : + _formatters.push_back(std::unique_ptr(new details::t_formatter())); + break; - case('v') : - _formatters.push_back(std::unique_ptr(new details::v_formatter())); - break; + case('v') : + _formatters.push_back(std::unique_ptr(new details::v_formatter())); + break; - case('a') : - _formatters.push_back(std::unique_ptr(new details::a_formatter())); - break; + case('a') : + _formatters.push_back(std::unique_ptr(new details::a_formatter())); + break; - case('A') : - _formatters.push_back(std::unique_ptr(new details::A_formatter())); - break; + case('A') : + _formatters.push_back(std::unique_ptr(new details::A_formatter())); + break; - case('b') : - case('h') : - _formatters.push_back(std::unique_ptr(new details::b_formatter())); - break; + case('b') : + case('h') : + _formatters.push_back(std::unique_ptr(new details::b_formatter())); + break; - case('B') : - _formatters.push_back(std::unique_ptr(new details::B_formatter())); - break; - case('c') : - _formatters.push_back(std::unique_ptr(new details::c_formatter())); - break; + case('B') : + _formatters.push_back(std::unique_ptr(new details::B_formatter())); + break; + case('c') : + _formatters.push_back(std::unique_ptr(new details::c_formatter())); + break; - case('C') : - _formatters.push_back(std::unique_ptr(new details::C_formatter())); - break; + case('C') : + _formatters.push_back(std::unique_ptr(new details::C_formatter())); + break; - case('Y') : - _formatters.push_back(std::unique_ptr(new details::Y_formatter())); - break; + case('Y') : + _formatters.push_back(std::unique_ptr(new details::Y_formatter())); + break; - case('D') : - case('x') : + case('D') : + case('x') : - _formatters.push_back(std::unique_ptr(new details::D_formatter())); - break; + _formatters.push_back(std::unique_ptr(new details::D_formatter())); + break; - case('m') : - _formatters.push_back(std::unique_ptr(new details::m_formatter())); - break; + case('m') : + _formatters.push_back(std::unique_ptr(new details::m_formatter())); + break; - case('d') : - _formatters.push_back(std::unique_ptr(new details::d_formatter())); - break; + case('d') : + _formatters.push_back(std::unique_ptr(new details::d_formatter())); + break; - case('H') : - _formatters.push_back(std::unique_ptr(new details::H_formatter())); - break; + case('H') : + _formatters.push_back(std::unique_ptr(new details::H_formatter())); + break; - case('I') : - _formatters.push_back(std::unique_ptr(new details::I_formatter())); - break; + case('I') : + _formatters.push_back(std::unique_ptr(new details::I_formatter())); + break; - case('M') : - _formatters.push_back(std::unique_ptr(new details::M_formatter())); - break; + case('M') : + _formatters.push_back(std::unique_ptr(new details::M_formatter())); + break; - case('S') : - _formatters.push_back(std::unique_ptr(new details::S_formatter())); - break; + case('S') : + _formatters.push_back(std::unique_ptr(new details::S_formatter())); + break; - case('e') : - _formatters.push_back(std::unique_ptr(new details::e_formatter())); - break; + case('e') : + _formatters.push_back(std::unique_ptr(new details::e_formatter())); + break; - case('p') : - _formatters.push_back(std::unique_ptr(new details::p_formatter())); - break; + case('p') : + _formatters.push_back(std::unique_ptr(new details::p_formatter())); + break; - case('r') : - _formatters.push_back(std::unique_ptr(new details::r_formatter())); - break; + case('r') : + _formatters.push_back(std::unique_ptr(new details::r_formatter())); + break; - case('R') : - _formatters.push_back(std::unique_ptr(new details::R_formatter())); - break; + case('R') : + _formatters.push_back(std::unique_ptr(new details::R_formatter())); + break; - case('T') : - case('X') : - _formatters.push_back(std::unique_ptr(new details::T_formatter())); - break; + case('T') : + case('X') : + _formatters.push_back(std::unique_ptr(new details::T_formatter())); + break; - case('z') : - _formatters.push_back(std::unique_ptr(new details::z_formatter())); - break; + case('z') : + _formatters.push_back(std::unique_ptr(new details::z_formatter())); + break; - case ('+'): - _formatters.push_back(std::unique_ptr(new details::full_formatter())); - break; + case ('+'): + _formatters.push_back(std::unique_ptr(new details::full_formatter())); + break; - default: //Unkown flag appears as is - _formatters.push_back(std::unique_ptr(new details::ch_formatter('%'))); - _formatters.push_back(std::unique_ptr(new details::ch_formatter(flag))); - break; - } + default: //Unkown flag appears as is + _formatters.push_back(std::unique_ptr(new details::ch_formatter('%'))); + _formatters.push_back(std::unique_ptr(new details::ch_formatter(flag))); + break; + } } inline void spdlog::pattern_formatter::format(details::log_msg& msg) { - try - { - auto tm_time = details::os::localtime(log_clock::to_time_t(msg.time)); - for (auto &f : _formatters) - { - f->format(msg, tm_time); - } - //write eol - msg.formatted << details::os::eol(); - } - catch(const details::fmt::FormatError& e) - { - throw spdlog_ex(details::fmt::format("formatting error while processing format string: {}", e.what())); - } + try + { + auto tm_time = details::os::localtime(log_clock::to_time_t(msg.time)); + for (auto &f : _formatters) + { + f->format(msg, tm_time); + } + //write eol + msg.formatted << details::os::eol(); + } + catch(const details::fmt::FormatError& e) + { + throw spdlog_ex(details::fmt::format("formatting error while processing format string: {}", e.what())); + } } diff --git a/include/spdlog/details/registry.h b/include/spdlog/details/registry.h index 2fee86d7..c04989e8 100644 --- a/include/spdlog/details/registry.h +++ b/include/spdlog/details/registry.h @@ -44,114 +44,114 @@ namespace details class registry { public: - std::shared_ptr get(const std::string& logger_name) - { - std::lock_guard lock(_mutex); - auto found = _loggers.find(logger_name); - return found == _loggers.end() ? nullptr : found->second; - } + std::shared_ptr get(const std::string& logger_name) + { + std::lock_guard lock(_mutex); + auto found = _loggers.find(logger_name); + return found == _loggers.end() ? nullptr : found->second; + } - template - std::shared_ptr create(const std::string& logger_name, const It& sinks_begin, const It& sinks_end) - { - std::lock_guard lock(_mutex); - //If already exists, just return it - auto found = _loggers.find(logger_name); - if (found != _loggers.end()) - return found->second; - std::shared_ptr new_logger; - if (_async_mode) - new_logger = std::make_shared(logger_name, sinks_begin, sinks_end, _async_q_size); - else - new_logger = std::make_shared(logger_name, sinks_begin, sinks_end); + template + std::shared_ptr create(const std::string& logger_name, const It& sinks_begin, const It& sinks_end) + { + std::lock_guard lock(_mutex); + //If already exists, just return it + auto found = _loggers.find(logger_name); + if (found != _loggers.end()) + return found->second; + std::shared_ptr new_logger; + if (_async_mode) + new_logger = std::make_shared(logger_name, sinks_begin, sinks_end, _async_q_size); + else + new_logger = std::make_shared(logger_name, sinks_begin, sinks_end); - if (_formatter) - new_logger->set_formatter(_formatter); - new_logger->set_level(_level); - _loggers[logger_name] = new_logger; - return new_logger; - } + if (_formatter) + new_logger->set_formatter(_formatter); + new_logger->set_level(_level); + _loggers[logger_name] = new_logger; + return new_logger; + } - void drop(const std::string& logger_name) - { - std::lock_guard lock(_mutex); - _loggers.erase(logger_name); - } + void drop(const std::string& logger_name) + { + std::lock_guard lock(_mutex); + _loggers.erase(logger_name); + } - std::shared_ptr create(const std::string& logger_name, sinks_init_list sinks) - { - return create(logger_name, sinks.begin(), sinks.end()); - } + std::shared_ptr create(const std::string& logger_name, sinks_init_list sinks) + { + return create(logger_name, sinks.begin(), sinks.end()); + } - std::shared_ptr create(const std::string& logger_name, sink_ptr sink) - { - return create(logger_name, { sink }); - } + std::shared_ptr create(const std::string& logger_name, sink_ptr sink) + { + return create(logger_name, { sink }); + } - void formatter(formatter_ptr f) - { - std::lock_guard lock(_mutex); - _formatter = f; - for (auto& l : _loggers) - l.second->set_formatter(_formatter); - } + void formatter(formatter_ptr f) + { + std::lock_guard lock(_mutex); + _formatter = f; + for (auto& l : _loggers) + l.second->set_formatter(_formatter); + } - void set_pattern(const std::string& pattern) - { - std::lock_guard lock(_mutex); - _formatter = std::make_shared(pattern); - for (auto& l : _loggers) - l.second->set_formatter(_formatter); + void set_pattern(const std::string& pattern) + { + std::lock_guard lock(_mutex); + _formatter = std::make_shared(pattern); + for (auto& l : _loggers) + l.second->set_formatter(_formatter); - } + } - void set_level(level::level_enum log_level) - { - std::lock_guard lock(_mutex); - for (auto& l : _loggers) - l.second->set_level(log_level); - } + void set_level(level::level_enum log_level) + { + std::lock_guard lock(_mutex); + for (auto& l : _loggers) + l.second->set_level(log_level); + } - void set_async_mode(size_t q_size) - { - std::lock_guard lock(_mutex); - _async_mode = true; - _async_q_size = q_size; - } + void set_async_mode(size_t q_size) + { + std::lock_guard lock(_mutex); + _async_mode = true; + _async_q_size = q_size; + } - void set_sync_mode() - { - std::lock_guard lock(_mutex); - _async_mode = false; - } + void set_sync_mode() + { + std::lock_guard lock(_mutex); + _async_mode = false; + } - void stop_all() - { - std::lock_guard lock(_mutex); - _level = level::off; - for (auto& l : _loggers) - l.second->stop(); - } + void stop_all() + { + std::lock_guard lock(_mutex); + _level = level::off; + for (auto& l : _loggers) + l.second->stop(); + } - static registry& instance() - { - static registry s_instance; - return s_instance; - } + static registry& instance() + { + static registry s_instance; + return s_instance; + } private: - registry() = default; - registry(const registry&) = delete; - registry& operator=(const registry&) = delete; - std::mutex _mutex; - std::unordered_map > _loggers; - formatter_ptr _formatter; - level::level_enum _level = level::info; - bool _async_mode = false; - size_t _async_q_size = 0; + registry() = default; + registry(const registry&) = delete; + registry& operator=(const registry&) = delete; + std::mutex _mutex; + std::unordered_map > _loggers; + formatter_ptr _formatter; + level::level_enum _level = level::info; + bool _async_mode = false; + size_t _async_q_size = 0; }; } } diff --git a/include/spdlog/details/spdlog_impl.h b/include/spdlog/details/spdlog_impl.h index 6b72f24b..8b8adeb7 100644 --- a/include/spdlog/details/spdlog_impl.h +++ b/include/spdlog/details/spdlog_impl.h @@ -34,62 +34,62 @@ inline std::shared_ptr spdlog::get(const std::string& name) { - return details::registry::instance().get(name); + return details::registry::instance().get(name); } inline void spdlog::drop(const std::string &name) { - details::registry::instance().drop(name); + details::registry::instance().drop(name); } // Create multi/single threaded rotating file logger inline std::shared_ptr spdlog::rotating_logger_mt(const std::string& logger_name, const std::string& filename, size_t max_file_size, size_t max_files, bool auto_flush) { - return create(logger_name, filename, "txt", max_file_size, max_files, auto_flush); + return create(logger_name, filename, "txt", max_file_size, max_files, auto_flush); } inline std::shared_ptr spdlog::rotating_logger_st(const std::string& logger_name, const std::string& filename, size_t max_file_size, size_t max_files, bool auto_flush) { - return create(logger_name, filename, "txt", max_file_size, max_files, auto_flush); + return create(logger_name, filename, "txt", max_file_size, max_files, auto_flush); } // Create file logger which creates new file at midnight): inline std::shared_ptr spdlog::daily_logger_mt(const std::string& logger_name, const std::string& filename, bool auto_flush) { - return create(logger_name, filename, "txt", auto_flush); + return create(logger_name, filename, "txt", auto_flush); } inline std::shared_ptr spdlog::daily_logger_st(const std::string& logger_name, const std::string& filename, bool auto_flush) { - return create(logger_name, filename, "txt", auto_flush); + return create(logger_name, filename, "txt", auto_flush); } // Create stdout/stderr loggers inline std::shared_ptr spdlog::stdout_logger_mt(const std::string& logger_name) { - return create(logger_name); + return create(logger_name); } inline std::shared_ptr spdlog::stdout_logger_st(const std::string& logger_name) { - return create(logger_name); + return create(logger_name); } inline std::shared_ptr spdlog::stderr_logger_mt(const std::string& logger_name) { - return create(logger_name); + return create(logger_name); } inline std::shared_ptr spdlog::stderr_logger_st(const std::string& logger_name) { - return create(logger_name); + return create(logger_name); } #ifdef __linux__ // Create syslog logger inline std::shared_ptr spdlog::syslog_logger(const std::string& logger_name, const std::string& syslog_ident, int syslog_option) { - return create(logger_name, syslog_ident, syslog_option); + return create(logger_name, syslog_ident, syslog_option); } #endif @@ -98,51 +98,51 @@ inline std::shared_ptr spdlog::syslog_logger(const std::string& inline std::shared_ptr spdlog::create(const std::string& logger_name, spdlog::sinks_init_list sinks) { - return details::registry::instance().create(logger_name, sinks); + return details::registry::instance().create(logger_name, sinks); } template inline std::shared_ptr spdlog::create(const std::string& logger_name, const Args&... args) { - sink_ptr sink = std::make_shared(args...); - return details::registry::instance().create(logger_name, { sink }); + sink_ptr sink = std::make_shared(args...); + return details::registry::instance().create(logger_name, { sink }); } template inline std::shared_ptr spdlog::create(const std::string& logger_name, const It& sinks_begin, const It& sinks_end) { - return details::registry::instance().create(logger_name, sinks_begin, sinks_end); + return details::registry::instance().create(logger_name, sinks_begin, sinks_end); } inline void spdlog::set_formatter(spdlog::formatter_ptr f) { - details::registry::instance().formatter(f); + details::registry::instance().formatter(f); } inline void spdlog::set_pattern(const std::string& format_string) { - return details::registry::instance().set_pattern(format_string); + return details::registry::instance().set_pattern(format_string); } inline void spdlog::set_level(level::level_enum log_level) { - return details::registry::instance().set_level(log_level); + return details::registry::instance().set_level(log_level); } inline void spdlog::set_async_mode(size_t queue_size) { - details::registry::instance().set_async_mode(queue_size); + details::registry::instance().set_async_mode(queue_size); } inline void spdlog::set_sync_mode() { - details::registry::instance().set_sync_mode(); + details::registry::instance().set_sync_mode(); } inline void spdlog::stop() { - return details::registry::instance().stop_all(); + return details::registry::instance().stop_all(); } diff --git a/include/spdlog/formatter.h b/include/spdlog/formatter.h index 35ea0416..db15938b 100644 --- a/include/spdlog/formatter.h +++ b/include/spdlog/formatter.h @@ -34,23 +34,23 @@ class flag_formatter; class formatter { public: - virtual ~formatter() {} - virtual void format(details::log_msg& msg) = 0; + virtual ~formatter() {} + virtual void format(details::log_msg& msg) = 0; }; class pattern_formatter : public formatter { public: - explicit pattern_formatter(const std::string& pattern); - pattern_formatter(const pattern_formatter&) = delete; - pattern_formatter& operator=(const pattern_formatter&) = delete; - void format(details::log_msg& msg) override; + explicit pattern_formatter(const std::string& pattern); + pattern_formatter(const pattern_formatter&) = delete; + pattern_formatter& operator=(const pattern_formatter&) = delete; + void format(details::log_msg& msg) override; private: - const std::string _pattern; - std::vector> _formatters; - void handle_flag(char flag); - void compile_pattern(const std::string& pattern); + const std::string _pattern; + std::vector> _formatters; + void handle_flag(char flag); + void compile_pattern(const std::string& pattern); }; } diff --git a/include/spdlog/logger.h b/include/spdlog/logger.h index 6137e81f..88c52b95 100644 --- a/include/spdlog/logger.h +++ b/include/spdlog/logger.h @@ -47,88 +47,88 @@ class line_logger; class logger { public: - logger(const std::string& logger_name, sink_ptr single_sink); - logger(const std::string& name, sinks_init_list); - template - logger(const std::string& name, const It& begin, const It& end); + logger(const std::string& logger_name, sink_ptr single_sink); + logger(const std::string& name, sinks_init_list); + template + logger(const std::string& name, const It& begin, const It& end); - virtual ~logger(); - logger(const logger&) = delete; - logger& operator=(const logger&) = delete; + virtual ~logger(); + logger(const logger&) = delete; + logger& operator=(const logger&) = delete; - void set_level(level::level_enum); - level::level_enum level() const; + void set_level(level::level_enum); + level::level_enum level() const; - const std::string& name() const; - bool should_log(level::level_enum) const; + const std::string& name() const; + bool should_log(level::level_enum) const; - //Stop logging - void stop(); + //Stop logging + void stop(); - template - details::line_logger trace(const char* fmt, const Args&... args); + template + details::line_logger trace(const char* fmt, const Args&... args); - template - details::line_logger debug(const char* fmt, const Args&... args); + template + details::line_logger debug(const char* fmt, const Args&... args); - template - details::line_logger info(const char* fmt, const Args&... args); + template + details::line_logger info(const char* fmt, const Args&... args); - template - details::line_logger notice(const char* fmt, const Args&... args); + template + details::line_logger notice(const char* fmt, const Args&... args); - template - details::line_logger warn(const char* fmt, const Args&... args); + template + details::line_logger warn(const char* fmt, const Args&... args); - template details::line_logger error(const char* fmt, const Args&... args); + template details::line_logger error(const char* fmt, const Args&... args); - template - details::line_logger critical(const char* fmt, const Args&... args); + template + details::line_logger critical(const char* fmt, const Args&... args); - template - details::line_logger alert(const char* fmt, const Args&... args); + template + details::line_logger alert(const char* fmt, const Args&... args); - template - details::line_logger emerg(const char* fmt, const Args&... args); + template + details::line_logger emerg(const char* fmt, const Args&... args); - //API to support logger.info() << ".." call style - details::line_logger trace(); - details::line_logger debug(); - details::line_logger info(); - details::line_logger notice(); - details::line_logger warn(); - details::line_logger error(); - details::line_logger critical(); - details::line_logger alert(); - details::line_logger emerg(); + //API to support logger.info() << ".." call style + details::line_logger trace(); + details::line_logger debug(); + details::line_logger info(); + details::line_logger notice(); + details::line_logger warn(); + details::line_logger error(); + details::line_logger critical(); + details::line_logger alert(); + details::line_logger emerg(); - // Create log message with the given level, no matter what is the actual logger's level - template - details::line_logger force_log(level::level_enum lvl, const char* fmt, const Args&... args); + // Create log message with the given level, no matter what is the actual logger's level + template + details::line_logger force_log(level::level_enum lvl, const char* fmt, const Args&... args); - // Set the format of the log messages from this logger - void set_pattern(const std::string&); - void set_formatter(formatter_ptr); + // Set the format of the log messages from this logger + void set_pattern(const std::string&); + void set_formatter(formatter_ptr); protected: - virtual void _log_msg(details::log_msg&); - virtual void _set_pattern(const std::string&); - virtual void _set_formatter(formatter_ptr); - virtual void _stop(); - details::line_logger _log_if_enabled(level::level_enum lvl); - template - details::line_logger _log_if_enabled(level::level_enum lvl, const char* fmt, const Args&... args); + virtual void _log_msg(details::log_msg&); + virtual void _set_pattern(const std::string&); + virtual void _set_formatter(formatter_ptr); + virtual void _stop(); + details::line_logger _log_if_enabled(level::level_enum lvl); + template + details::line_logger _log_if_enabled(level::level_enum lvl, const char* fmt, const Args&... args); - friend details::line_logger; - std::string _name; - std::vector _sinks; - formatter_ptr _formatter; - std::atomic_int _level; + friend details::line_logger; + std::string _name; + std::vector _sinks; + formatter_ptr _formatter; + std::atomic_int _level; }; } diff --git a/include/spdlog/sinks/base_sink.h b/include/spdlog/sinks/base_sink.h index f1647ae0..c0135115 100644 --- a/include/spdlog/sinks/base_sink.h +++ b/include/spdlog/sinks/base_sink.h @@ -46,22 +46,22 @@ template class base_sink:public sink { public: - base_sink():_mutex() {} - virtual ~base_sink() = default; + base_sink():_mutex() {} + virtual ~base_sink() = default; - base_sink(const base_sink&) = delete; - base_sink& operator=(const base_sink&) = delete; + base_sink(const base_sink&) = delete; + base_sink& operator=(const base_sink&) = delete; - void log(const details::log_msg& msg) override - { - std::lock_guard lock(_mutex); - _sink_it(msg); - } + void log(const details::log_msg& msg) override + { + std::lock_guard lock(_mutex); + _sink_it(msg); + } protected: - virtual void _sink_it(const details::log_msg& msg) = 0; - Mutex _mutex; + virtual void _sink_it(const details::log_msg& msg) = 0; + Mutex _mutex; }; } } diff --git a/include/spdlog/sinks/file_sinks.h b/include/spdlog/sinks/file_sinks.h index 3e78d576..5cfc8ddc 100644 --- a/include/spdlog/sinks/file_sinks.h +++ b/include/spdlog/sinks/file_sinks.h @@ -43,20 +43,20 @@ template class simple_file_sink : public base_sink { public: - explicit simple_file_sink(const std::string &filename, - bool auto_flush=false): - _file_helper(auto_flush) - { - _file_helper.open(filename); - } + explicit simple_file_sink(const std::string &filename, + bool auto_flush=false): + _file_helper(auto_flush) + { + _file_helper.open(filename); + } protected: - void _sink_it(const details::log_msg& msg) override - { - _file_helper.write(msg); - } + void _sink_it(const details::log_msg& msg) override + { + _file_helper.write(msg); + } private: - details::file_helper _file_helper; + details::file_helper _file_helper; }; typedef simple_file_sink simple_file_sink_mt; @@ -69,80 +69,80 @@ template class rotating_file_sink : public base_sink { public: - rotating_file_sink(const std::string &base_filename, const std::string &extension, - std::size_t max_size, std::size_t max_files, - bool auto_flush=false): - _base_filename(base_filename), - _extension(extension), - _max_size(max_size), - _max_files(max_files), - _current_size(0), - _file_helper(auto_flush) - { - _file_helper.open(calc_filename(_base_filename, 0, _extension)); - } + rotating_file_sink(const std::string &base_filename, const std::string &extension, + std::size_t max_size, std::size_t max_files, + bool auto_flush=false): + _base_filename(base_filename), + _extension(extension), + _max_size(max_size), + _max_files(max_files), + _current_size(0), + _file_helper(auto_flush) + { + _file_helper.open(calc_filename(_base_filename, 0, _extension)); + } protected: - void _sink_it(const details::log_msg& msg) override - { - _current_size += msg.formatted.size(); - if (_current_size > _max_size) - { - _rotate(); - _current_size = msg.formatted.size(); - } - _file_helper.write(msg); - } + void _sink_it(const details::log_msg& msg) override + { + _current_size += msg.formatted.size(); + if (_current_size > _max_size) + { + _rotate(); + _current_size = msg.formatted.size(); + } + _file_helper.write(msg); + } private: - static std::string calc_filename(const std::string& filename, std::size_t index, const std::string& extension) - { - details::fmt::MemoryWriter w; - if (index) - w.write("{}.{}.{}", filename, index, extension); - else - w.write("{}.{}", filename, extension); - return w.str(); - } + static std::string calc_filename(const std::string& filename, std::size_t index, const std::string& extension) + { + details::fmt::MemoryWriter w; + if (index) + w.write("{}.{}.{}", filename, index, extension); + else + w.write("{}.{}", filename, extension); + return w.str(); + } - // Rotate files: - // log.txt -> log.1.txt - // log.1.txt -> log2.txt - // log.2.txt -> log3.txt - // log.3.txt -> delete + // Rotate files: + // log.txt -> log.1.txt + // log.1.txt -> log2.txt + // log.2.txt -> log3.txt + // log.3.txt -> delete - void _rotate() - { - _file_helper.close(); - for (auto i = _max_files; i > 0; --i) - { - std::string src = calc_filename(_base_filename, i - 1, _extension); - std::string target = calc_filename(_base_filename, i, _extension); + void _rotate() + { + _file_helper.close(); + for (auto i = _max_files; i > 0; --i) + { + std::string src = calc_filename(_base_filename, i - 1, _extension); + std::string target = calc_filename(_base_filename, i, _extension); - if (details::file_helper::file_exists(target)) - { - if (std::remove(target.c_str()) != 0) - { - throw spdlog_ex("rotating_file_sink: failed removing " + target); - } - } - if (details::file_helper::file_exists(src) && std::rename(src.c_str(), target.c_str())) - { - throw spdlog_ex("rotating_file_sink: failed renaming " + src + " to " + target); - } - } - _file_helper.reopen(true); - } - std::string _base_filename; - std::string _extension; - std::size_t _max_size; - std::size_t _max_files; - std::size_t _current_size; - details::file_helper _file_helper; + if (details::file_helper::file_exists(target)) + { + if (std::remove(target.c_str()) != 0) + { + throw spdlog_ex("rotating_file_sink: failed removing " + target); + } + } + if (details::file_helper::file_exists(src) && std::rename(src.c_str(), target.c_str())) + { + throw spdlog_ex("rotating_file_sink: failed renaming " + src + " to " + target); + } + } + _file_helper.reopen(true); + } + std::string _base_filename; + std::string _extension; + std::size_t _max_size; + std::size_t _max_files; + std::size_t _current_size; + details::file_helper _file_helper; }; typedef rotating_file_sink rotating_file_sink_mt; @@ -155,56 +155,56 @@ template class daily_file_sink:public base_sink { public: - explicit daily_file_sink(const std::string& base_filename, - const std::string& extension, - bool auto_flush=false): - _base_filename(base_filename), - _extension(extension), - _midnight_tp (_calc_midnight_tp() ), - _file_helper(auto_flush) - { - _file_helper.open(calc_filename(_base_filename, _extension)); - } + explicit daily_file_sink(const std::string& base_filename, + const std::string& extension, + bool auto_flush=false): + _base_filename(base_filename), + _extension(extension), + _midnight_tp (_calc_midnight_tp() ), + _file_helper(auto_flush) + { + _file_helper.open(calc_filename(_base_filename, _extension)); + } protected: - void _sink_it(const details::log_msg& msg) override - { - if (std::chrono::system_clock::now() >= _midnight_tp) - { - _file_helper.close(); - _file_helper.open(calc_filename(_base_filename, _extension)); - _midnight_tp = _calc_midnight_tp(); - } - _file_helper.write(msg); - } + void _sink_it(const details::log_msg& msg) override + { + if (std::chrono::system_clock::now() >= _midnight_tp) + { + _file_helper.close(); + _file_helper.open(calc_filename(_base_filename, _extension)); + _midnight_tp = _calc_midnight_tp(); + } + _file_helper.write(msg); + } private: - // Return next midnight's time_point - static std::chrono::system_clock::time_point _calc_midnight_tp() - { - using namespace std::chrono; - auto now = system_clock::now(); - time_t tnow = std::chrono::system_clock::to_time_t(now); - tm date = spdlog::details::os::localtime(tnow); - date.tm_hour = date.tm_min = date.tm_sec = 0; - auto midnight = std::chrono::system_clock::from_time_t(std::mktime(&date)); - return system_clock::time_point(midnight + hours(24)); - } + // Return next midnight's time_point + static std::chrono::system_clock::time_point _calc_midnight_tp() + { + using namespace std::chrono; + auto now = system_clock::now(); + time_t tnow = std::chrono::system_clock::to_time_t(now); + tm date = spdlog::details::os::localtime(tnow); + date.tm_hour = date.tm_min = date.tm_sec = 0; + auto midnight = std::chrono::system_clock::from_time_t(std::mktime(&date)); + return system_clock::time_point(midnight + hours(24)); + } - //Create filename for the form basename.YYYY-MM-DD.extension - static std::string calc_filename(const std::string& basename, const std::string& extension) - { - std::tm tm = spdlog::details::os::localtime(); - details::fmt::MemoryWriter w; - w.write("{}.{:04d}-{:02d}-{:02d}.{}", basename, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, extension); - return w.str(); - } + //Create filename for the form basename.YYYY-MM-DD.extension + static std::string calc_filename(const std::string& basename, const std::string& extension) + { + std::tm tm = spdlog::details::os::localtime(); + details::fmt::MemoryWriter w; + w.write("{}.{:04d}-{:02d}-{:02d}.{}", basename, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, extension); + return w.str(); + } - std::string _base_filename; - std::string _extension; - std::chrono::system_clock::time_point _midnight_tp; - details::file_helper _file_helper; + std::string _base_filename; + std::string _extension; + std::chrono::system_clock::time_point _midnight_tp; + details::file_helper _file_helper; }; diff --git a/include/spdlog/sinks/null_sink.h b/include/spdlog/sinks/null_sink.h index 2cd416a9..1fedcb8f 100644 --- a/include/spdlog/sinks/null_sink.h +++ b/include/spdlog/sinks/null_sink.h @@ -37,8 +37,8 @@ template class null_sink : public base_sink < Mutex > { protected: - void _sink_it(const details::log_msg&) override - {} + void _sink_it(const details::log_msg&) override + {} }; typedef null_sink null_sink_st; diff --git a/include/spdlog/sinks/ostream_sink.h b/include/spdlog/sinks/ostream_sink.h index 68ecec87..c8048abf 100644 --- a/include/spdlog/sinks/ostream_sink.h +++ b/include/spdlog/sinks/ostream_sink.h @@ -39,17 +39,17 @@ template class ostream_sink: public base_sink { public: - explicit ostream_sink(std::ostream& os) :_ostream(os) {} - ostream_sink(const ostream_sink&) = delete; - ostream_sink& operator=(const ostream_sink&) = delete; - virtual ~ostream_sink() = default; + explicit ostream_sink(std::ostream& os) :_ostream(os) {} + ostream_sink(const ostream_sink&) = delete; + ostream_sink& operator=(const ostream_sink&) = delete; + virtual ~ostream_sink() = default; protected: - virtual void _sink_it(const details::log_msg& msg) override - { - _ostream.write(msg.formatted.data(), msg.formatted.size()); - } - std::ostream& _ostream; + virtual void _sink_it(const details::log_msg& msg) override + { + _ostream.write(msg.formatted.data(), msg.formatted.size()); + } + std::ostream& _ostream; }; typedef ostream_sink ostream_sink_mt; diff --git a/include/spdlog/sinks/sink.h b/include/spdlog/sinks/sink.h index 0905d52f..132ed2d7 100644 --- a/include/spdlog/sinks/sink.h +++ b/include/spdlog/sinks/sink.h @@ -33,8 +33,8 @@ namespace sinks class sink { public: - virtual ~sink() {} - virtual void log(const details::log_msg& msg) = 0; + virtual ~sink() {} + virtual void log(const details::log_msg& msg) = 0; }; } } diff --git a/include/spdlog/sinks/stdout_sinks.h b/include/spdlog/sinks/stdout_sinks.h index b633b2dc..059a11c8 100644 --- a/include/spdlog/sinks/stdout_sinks.h +++ b/include/spdlog/sinks/stdout_sinks.h @@ -38,7 +38,7 @@ template class stdout_sink : public ostream_sink { public: - stdout_sink() : ostream_sink(std::cout) {} + stdout_sink() : ostream_sink(std::cout) {} }; @@ -50,7 +50,7 @@ template class stderr_sink : public ostream_sink { public: - stderr_sink() : ostream_sink(std::cerr) {} + stderr_sink() : ostream_sink(std::cerr) {} }; typedef stderr_sink stderr_sink_mt; diff --git a/include/spdlog/sinks/syslog_sink.h b/include/spdlog/sinks/syslog_sink.h index 9da77e5e..ed5eb929 100644 --- a/include/spdlog/sinks/syslog_sink.h +++ b/include/spdlog/sinks/syslog_sink.h @@ -47,50 +47,50 @@ class syslog_sink : public sink { public: // - syslog_sink(const std::string& ident = "", int syslog_option=0, int syslog_facility=LOG_USER): - _ident(ident) - { - _priorities[static_cast(level::trace)] = LOG_DEBUG; - _priorities[static_cast(level::debug)] = LOG_DEBUG; - _priorities[static_cast(level::info)] = LOG_INFO; - _priorities[static_cast(level::notice)] = LOG_NOTICE; - _priorities[static_cast(level::warn)] = LOG_WARNING; - _priorities[static_cast(level::err)] = LOG_ERR; - _priorities[static_cast(level::critical)] = LOG_CRIT; - _priorities[static_cast(level::alert)] = LOG_ALERT; - _priorities[static_cast(level::emerg)] = LOG_EMERG; - _priorities[static_cast(level::off)] = LOG_INFO; + syslog_sink(const std::string& ident = "", int syslog_option=0, int syslog_facility=LOG_USER): + _ident(ident) + { + _priorities[static_cast(level::trace)] = LOG_DEBUG; + _priorities[static_cast(level::debug)] = LOG_DEBUG; + _priorities[static_cast(level::info)] = LOG_INFO; + _priorities[static_cast(level::notice)] = LOG_NOTICE; + _priorities[static_cast(level::warn)] = LOG_WARNING; + _priorities[static_cast(level::err)] = LOG_ERR; + _priorities[static_cast(level::critical)] = LOG_CRIT; + _priorities[static_cast(level::alert)] = LOG_ALERT; + _priorities[static_cast(level::emerg)] = LOG_EMERG; + _priorities[static_cast(level::off)] = LOG_INFO; //set ident to be program name if empty - ::openlog(_ident.empty()? nullptr:_ident.c_str(), syslog_option, syslog_facility); - } - ~syslog_sink() - { + ::openlog(_ident.empty()? nullptr:_ident.c_str(), syslog_option, syslog_facility); + } + ~syslog_sink() + { ::closelog(); - } + } - syslog_sink(const syslog_sink&) = delete; - syslog_sink& operator=(const syslog_sink&) = delete; + syslog_sink(const syslog_sink&) = delete; + syslog_sink& operator=(const syslog_sink&) = delete; - void log(const details::log_msg &msg) override - { - ::syslog(syslog_prio_from_level(msg), "%s", msg.formatted.str().c_str()); - } + void log(const details::log_msg &msg) override + { + ::syslog(syslog_prio_from_level(msg), "%s", msg.formatted.str().c_str()); + } private: - std::array _priorities; - //must store the ident because the man says openlog might use the pointer as is and not a string copy - const std::string _ident; - - // - // Simply maps spdlog's log level to syslog priority level. - // - int syslog_prio_from_level(const details::log_msg &msg) const - { - return _priorities[static_cast(msg.level)]; - } + std::array _priorities; + //must store the ident because the man says openlog might use the pointer as is and not a string copy + const std::string _ident; + + // + // Simply maps spdlog's log level to syslog priority level. + // + int syslog_prio_from_level(const details::log_msg &msg) const + { + return _priorities[static_cast(msg.level)]; + } }; } }