/** roflcat Copyright (C) 2019 rexy712 This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef PRINTER_BASE_HPP #define PRINTER_BASE_HPP #include "cmd.hpp" #include //std::is_same #include //std::declval #define SHOW_TABS_STRING L"^I" #define LINE_NUMBERING_SPACE STRINGIFY(8) #define REAL_STRINGIFY(x) #x #define STRINGIFY(x) REAL_STRINGIFY(x) //name of struct generated by OPTIONAL_MEMBER_FUNC for given x #define HAS_FUNC(x) _determine_has_member_func_##x //generate utility struct to determine if a given class has a member function #define OPTIONAL_MEMBER_FUNC(x) \ template \ struct HAS_FUNC(x){ \ private: \ template \ struct check_s{}; \ template \ static char test(check_s*); \ template \ static int test(...); \ public: \ static constexpr bool value = std::is_same(nullptr))>::value; \ } //Defines an interface for the base classes //require a _print and an optional _reset function template class printer_base { private: OPTIONAL_MEMBER_FUNC(_reset); private: const bool m_show_ends = false; const int m_print_ln = PRINT_LINE_NEVER; const bool m_squeeze_blank = false; int m_squeeze_cnt = 0; bool m_newline = true; int m_line_num = 1; const wchar_t* const m_tab_str = L"\t"; const size_t m_tab_size = 1; protected: constexpr printer_base(void)noexcept = default; constexpr printer_base(const wchar_t* tabstr, const cmd_args& args)noexcept; ~printer_base(void)noexcept = default; public: constexpr Derived& print(wchar_t s)noexcept(noexcept(std::declval()._print(s))); constexpr Derived& print(const wchar_t* s)noexcept(noexcept(std::declval>().print(std::declval()))); constexpr Derived& print(char s); constexpr Derived& print(const char* s); constexpr Derived& reset(void); }; #endif