Last active
July 29, 2018 14:45
-
-
Save yossi-tahara/0c3f7ecf01618bda1ccc4b88cef6c43a to your computer and use it in GitHub Desktop.
第30回 可変長引数テンプレート応用編(C++版お手軽printf関数)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
cmake_minimum_required(VERSION 3.5.1) | |
project(sample) | |
find_package(Boost) | |
include_directories("${Boost_INCLUDE_DIR}") | |
if(MSVC) | |
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4 /EHsc") | |
else() | |
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -std=c++11") | |
endif() | |
add_executable(sample main.cpp xprintf.cpp xprintf.h) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
使用許諾書 | |
・本ソフトウェアは、ご自由にお使いください。 | |
・本ソフトウェアは、あるがままの姿で提供いたします。明示黙示を問わず、瑕疵がないこと、特定の目的に適合すること、使用地域における法令の規制等に合致すること、その他一切の保証をいたしません。 | |
・本ソフトウェアについては、無償で提供するものですので、何らかの不具合が発生した場合であっても、セオライドテクノロジーは、何らの責任も負いません。使用するかどうかのご判断も、ご自身でお願いいたします。 | |
・本ソフトウェアの利用により、お客様のハードウェア機器又はデータ等に支障が生じた場合でも、セオライド テクノロジーは一切その責任を負いません。データのバックアップ等については、お客様の責任において行ってください。 | |
・本ソフトウェアについては、第三者との間で著作権その他知的財産権上の紛争、 | |
・製造物責任法に基づく紛争等が生じた場合でも、セオライド テクノロジーは一切その責任を負いません。 | |
・上記の他、本ソフトウェアに関連して、直接的、もしくは、間接的に何らかの損害が発生したとしても、セオライド テクノロジーは、一切の責任を負いません。 | |
・セオライドテクノロジーは、本ソフトウェアに関する技術的サポートは行いません。 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include "xprintf.h" | |
#ifdef DEBUG | |
#define DEBUG_LOG(...) | |
#else | |
#define DEBUG_LOG(...) std::cout << __FILE__ << "(" << __LINE__ << ") : " << xprintf(__VA_ARGS__) | |
#endif | |
enum class Enum { Idle, Test }; | |
class Ratio | |
{ | |
int mFraction; | |
int mDenominator; | |
public: | |
Ratio(int iFraction, int iDenominator) : | |
mFraction(iFraction), mDenominator(iDenominator) | |
{ } | |
friend std::ostream& operator<<(std::ostream& iOStream, Ratio const& iRatio) | |
{ | |
iOStream << iRatio.mFraction << "/" << iRatio.mDenominator; | |
return iOStream; | |
} | |
}; | |
int main() | |
{ | |
std::cout << xprintf("%10s = %6.2f\n", "result", 2345.678); | |
DEBUG_LOG("%10s = %10.2f\n", "result", 3456.789); | |
Enum aEnum = Enum::Test; | |
DEBUG_LOG("%10s = %10d\n", "aEnum", aEnum); | |
Ratio aRatio(16, 9); | |
DEBUG_LOG("%10s = %10s\n", "aRatio", aRatio); | |
std::string aString="test"; | |
DEBUG_LOG("%10s = %10s\n", "aString", aString); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <boost/format.hpp> | |
#include "xprintf.h" | |
namespace internal | |
{ | |
std::string getString(boost::format& iFormat) | |
{ | |
return iFormat.str(); | |
} | |
template<typename tType> | |
boost::format& output(boost::format& iFormat, tType iParam) | |
{ | |
return iFormat % iParam; | |
} | |
boost::format& makeFormat(std::string const& iFormat) | |
{ | |
static boost::format aFormat(""); | |
aFormat.parse(iFormat); | |
return aFormat; | |
} | |
// 明示的実体化 | |
template boost::format& output(boost::format& iFormat, bool iParam); | |
template boost::format& output(boost::format& iFormat, char iParam); | |
template boost::format& output(boost::format& iFormat, signed char iParam); | |
template boost::format& output(boost::format& iFormat, short iParam); | |
template boost::format& output(boost::format& iFormat, int iParam); | |
template boost::format& output(boost::format& iFormat, long iParam); | |
template boost::format& output(boost::format& iFormat, long long iParam); | |
template boost::format& output(boost::format& iFormat, unsigned char iParam); | |
template boost::format& output(boost::format& iFormat, unsigned short iParam); | |
template boost::format& output(boost::format& iFormat, unsigned int iParam); | |
template boost::format& output(boost::format& iFormat, unsigned long long iParam); | |
template boost::format& output(boost::format& iFormat, float iParam); | |
template boost::format& output(boost::format& iFormat, double iParam); | |
template boost::format& output(boost::format& iFormat, long double iParam); | |
template boost::format& output(boost::format& iFormat, char const* iParam); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <type_traits> | |
#include <sstream> | |
namespace boost | |
{ | |
template<class charT, class Traits, class Alloc> class basic_format; | |
typedef basic_format<char, std::char_traits<char>, std::allocator<char>> format; | |
} | |
namespace internal | |
{ | |
std::string getString(boost::format& iFormat); | |
template<typename tType> | |
boost::format& output(boost::format& iFormat, tType iParam); | |
boost::format& makeFormat(std::string const& iFormat); | |
// ユーザ定義型対応 | |
template<typename tType, typename tEnable=void> | |
struct Out | |
{ | |
static boost::format& put(boost::format& iFormat, tType& iParam) | |
{ | |
std::stringstream ss; | |
ss << iParam; | |
return output(iFormat, ss.str().c_str()); | |
} | |
}; | |
template<typename tType> | |
struct Out<tType, typename std::enable_if<std::is_arithmetic<tType>::value>::type> | |
{ | |
static boost::format& put(boost::format& iFormat, tType& iParam) | |
{ | |
return output(iFormat, iParam); | |
} | |
}; | |
// scoped enum型にも対応 | |
template<typename tType> | |
struct Out<tType, typename std::enable_if<std::is_enum<tType>::value>::type> | |
{ | |
static boost::format& put(boost::format& iFormat, tType& iParam) | |
{ | |
return output(iFormat, static_cast<typename std::underlying_type<tType>::type>(iParam)); | |
} | |
}; | |
inline std::string xprintf_impl(boost::format& iFormat) | |
{ | |
return getString(iFormat); | |
} | |
template<typename tFirst, typename... tParams> | |
inline std::string xprintf_impl(boost::format& iFormat, tFirst iFirst, tParams... iParams) | |
{ | |
return xprintf_impl(Out<tFirst>::put(iFormat, iFirst), iParams...); | |
} | |
} | |
template<typename... tParams> | |
inline std::string xprintf(std::string const& iFormat, tParams... iParams) | |
{ | |
return internal::xprintf_impl(internal::makeFormat(iFormat), iParams...); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment