diff --git a/Makefile b/Makefile index 3272f6bfe039922453fa5c9a679814eae1bc29dd..53d0eb17f85c3dcf7632f5fa17191fa448278d40 100644 --- a/Makefile +++ b/Makefile @@ -9,30 +9,21 @@ PREFIX ?= /usr def: compile_library -compile_library: - $(CXX) $(CXXFLAGS) -c libr.cc -I . -o libr.o - $(AR) $(ARFLAGS) libr.a libr.o - install_header: [ ! -d $(PREFIX)/include/rlib ] || rm -rf $(PREFIX)/include/rlib cp -r . $(PREFIX)/include/rlib rm -rf $(PREFIX)/include/rlib/test $(PREFIX)/include/rlib/.git -install_library: compile_library - cp libr.a $(PREFIX)/lib/ - install_cmake: install_library [ ! -d $(PREFIX)/lib/cmake/rlib ] || rm -rf $(PREFIX)/lib/cmake/rlib [ ! -d $(PREFIX)/lib/cmake ] || cp -r cmake $(PREFIX)/lib/cmake/rlib -install: install_header install_library install_cmake +install: install_header install_cmake uninstall: rm -rf $(PREFIX)/include/rlib $(PREFIX)/lib/cmake/rlib - rm -f $(PREFIX)/lib/libr.a clean: - rm *.o *.a .PHONY: test diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 129368e5fd783b0215c6ed962049b4f1c601d545..a5e83076586f217a294a42e30d83b596fd43df5f 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -14,6 +14,5 @@ if(MSYS OR MINGW) add_definitions(-DRLIB_MINGW_DISABLE_TLS) endif() -add_library(r STATIC ../libr.cc) include_directories(..) diff --git a/cmake/rlib-config.cmake b/cmake/rlib-config.cmake index 18a57587445ae34fa310bf8a741689e3712cbcb3..0cc3a3ce2ba6e2832668adefed8d4685db3bdab0 100644 --- a/cmake/rlib-config.cmake +++ b/cmake/rlib-config.cmake @@ -1,7 +1,6 @@ # use this file if you want to install rlib set(rlib_INCLUDE_DIRS ${PREFIX}/include) -set(rlib_LIBRARIES ${PREFIX}/lib/libr.a) if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") # using clang diff --git a/libr.cc b/libr.cc deleted file mode 100644 index 006f5f3d5324d69d10523730594701e780058c29..0000000000000000000000000000000000000000 --- a/libr.cc +++ /dev/null @@ -1,28 +0,0 @@ -#include <rlib/log.hpp> //log_level_t -#include <rlib/stream.hpp> -#include <sstream> - -#if (RLIB_CXX_STD >= 2017) && (RLIB_COMPILER_ID != CC_MSVC) -#warning library should not be compiled under C++17. Or The library wont work for c++14 users. -#endif - -namespace rlib { - namespace impl { -// If libr.cc is built under C++17, and other header files are included in C++14 project, -// Then something wrong will happen. So DO NOT ignore the following definitions. NEVER. -//#if RLIB_CXX_STD < 2017 - bool enable_endl_flush = true; - int max_predefined_log_level = (int)log_level_t::DEBUG; - NullStreamBuf null_streambuf; -//#endif -//#ifndef RLIB_MINGW_DISABLE_TLS -//#if RLIB_CXX_STD < 2017 - thread_local std::stringstream _format_string_helper_ss; - thread_local std::stringstream to_string_by_sstream_ss; -//#endif -//#endif - } -//#if RLIB_CXX_STD < 2017 - std::ostream null_stream(&impl::null_streambuf); -//#endif -} diff --git a/log.hpp b/log.hpp index b338b12d34326757b28fada9a86cf486fd145cac..10b6babb24621cecc986530e8851622480e14357 100644 --- a/log.hpp +++ b/log.hpp @@ -36,11 +36,10 @@ namespace rlib { // Allow extension. enum class log_level_t : int { FATAL = 1, ERROR, WARNING, INFO, VERBOSE, DEBUG }; namespace impl { -#if RLIB_CXX_STD < 2017 - extern int max_predefined_log_level; -#else - inline int max_predefined_log_level = (int)log_level_t::DEBUG; -#endif + inline int &max_predefined_log_level() { + static int instance = (int)log_level_t::DEBUG; + return instance; + } } /* How to update log_level_t: @@ -109,10 +108,10 @@ namespace rlib { } // Warning: this method is not thread-safe. log_level_t register_log_level(const std::string &name) { - if(impl::max_predefined_log_level == INT_MAX) + if(impl::max_predefined_log_level() == INT_MAX) throw std::overflow_error("At most {}(INT_MAX) log_level is allowed."_format(INT_MAX)); - ++ impl::max_predefined_log_level; - log_level_t new_level = (log_level_t)impl::max_predefined_log_level; + ++ impl::max_predefined_log_level(); + log_level_t new_level = (log_level_t)impl::max_predefined_log_level(); custom_log_level_names.push_back({new_level, name}); return new_level; } diff --git a/stdio.hpp b/stdio.hpp index 54e05551bd47890297b227eead29f282cfb0e51c..80d6e6bfbb974b8812f3a7760ca50857fedc7ca8 100644 --- a/stdio.hpp +++ b/stdio.hpp @@ -96,25 +96,24 @@ namespace rlib { // implementations below -------------------------------- namespace impl { -#if RLIB_CXX_STD < 2017 - extern bool enable_endl_flush; -#else - inline bool enable_endl_flush = true; -#endif + inline bool &enable_endl_flush() { + static bool instance = true; + return instance; + } } inline bool sync_with_stdio(bool sync = true) noexcept { return std::ios::sync_with_stdio(sync); } inline bool enable_endl_flush(bool enable = true) noexcept { - return impl::enable_endl_flush = enable; + return impl::enable_endl_flush() = enable; } // Implements. template < class CharT, class Traits > inline std::basic_ostream<CharT, Traits>& endl(std::basic_ostream<CharT, Traits>& os) { os << RLIB_IMPL_ENDLINE; - if(impl::enable_endl_flush) + if(impl::enable_endl_flush()) os.flush(); return os; } diff --git a/stream.hpp b/stream.hpp index a3bf36d07378167394c6ced68f60fab8f56bfde2..93f77c25b061ac57b64be56718c3273c534b5963 100644 --- a/stream.hpp +++ b/stream.hpp @@ -10,16 +10,15 @@ namespace rlib { public: int overflow(int c) { return c; } }; -#if RLIB_CXX_STD < 2017 - extern NullStreamBuf null_streambuf; -#else - inline NullStreamBuf null_streambuf; -#endif + + inline NullStreamBuf & null_streambuf() { + static NullStreamBuf instance; + return instance; + } } -#if RLIB_CXX_STD < 2017 - extern std::ostream null_stream; -#else - inline std::ostream null_stream(&impl::null_streambuf); -#endif + inline std::ostream &null_stream() { + static std::ostream instance(impl::null_streambuf()); + return instance; + } } diff --git a/string.hpp b/string.hpp index 79d23b501f141be14b4a59dc93515f5a93805110..9fe79687a1eab5374f64b9f23f644786c421408e 100644 --- a/string.hpp +++ b/string.hpp @@ -24,6 +24,7 @@ #include <sstream> #include <type_traits> +// Intel C++ compiler has a pending bug for `thread_local inline` variable. #if RLIB_COMPILER_ID == CC_ICC #define RLIB_IMPL_SSTREAM_DISABLE_TLS #endif @@ -36,14 +37,14 @@ namespace rlib { // literals::_format, format_string, string::format namespace impl { #ifndef RLIB_IMPL_SSTREAM_DISABLE_TLS -#if RLIB_CXX_STD < 2017 -// Intel C++ compiler has a pending bug for `thread_local inline` variable. - thread_local extern std::stringstream to_string_by_sstream_ss; - thread_local extern std::stringstream _format_string_helper_ss; -#else - thread_local inline std::stringstream to_string_by_sstream_ss; - thread_local inline std::stringstream _format_string_helper_ss; -#endif + inline std::stringstream &to_string_by_sstream_ss() { + static thread_local std::stringstream instance; + return instance; + } + inline std::stringstream &_format_string_helper_ss() { + static thread_local std::stringstream instance; + return instance; + } #endif template <typename VarT> std::string to_string_by_sstream(VarT &thing) { @@ -52,7 +53,7 @@ namespace rlib { // Also fix mingw bug. But much slower! std::stringstream ss; #else - auto &ss = to_string_by_sstream_ss; + auto &ss = to_string_by_sstream_ss(); ss.str(std::string()); #endif ss << thing; @@ -65,7 +66,7 @@ namespace rlib { // Fix intel C++ bug https://software.intel.com/en-us/forums/intel-c-compiler/topic/784136 std::stringstream ss; #else - auto &ss = _format_string_helper_ss; // cached stringstream is much quicker. + auto &ss = _format_string_helper_ss(); // cached stringstream is much quicker. ss.str(std::string()); #endif size_t pos = 0, prev_pos = 0; diff --git a/test/Makefile b/test/Makefile index a81d86444a9921db0ae3e5244fe8c59c8f4a1ea0..edd67cbaeea2c5b9dfc1190853e50a7248be17fa 100644 --- a/test/Makefile +++ b/test/Makefile @@ -24,8 +24,8 @@ MODULES=string meta trait stdio sio scope_guard XTRA_FLAGS ?= CXXFLAGS=-I. -I../.. $(XTRA_FLAGS) STD ?= 14 -FLAGS11=-std=c++11 rlib/libr.a -FLAGS14=-std=c++14 rlib/libr.a +FLAGS11=-std=c++11 +FLAGS14=-std=c++14 FLAGS17=-std=c++17 ifeq ($(STD),11)