1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
|
#include <iostream>
#include <iomanip>
#include <string>
namespace manip
{
namespace detail
{
template < typename CHAR, typename TRAITS = std::char_traits<CHAR>,
typename ALLOC = std::allocator<CHAR> >
struct centre
{
template < typename STR_OR_CSTR >
centre( const STR_OR_CSTR& str, std::size_t width ) : str(str), width(width) {}
std::basic_string<CHAR,TRAITS,ALLOC> str ;
std::size_t width ;
template < typename OSTREAM >
friend OSTREAM& operator<< ( OSTREAM& stm, const centre& cntr )
{
std::size_t padl = 0 ;
std::size_t padr = 0 ;
if( cntr.width > cntr.str.size() )
{
padl = ( cntr.width - cntr.str.size() ) / 2 ;
padr = padl + ( cntr.width - cntr.str.size() ) % 2 ;
}
for( std::size_t i = 0 ; i < padl ; ++i ) stm << stm.widen(' ') ;
stm << cntr.str ;
for( std::size_t i = 0 ; i < padr ; ++i ) stm << stm.widen(' ') ;
return stm ;
}
};
}
template < typename CHAR > // centre c-style strings
detail::centre<CHAR> centre( const CHAR* cstr, std::size_t width )
{ return { cstr, width } ; }
template < typename CHAR, typename TRAITS, typename ALLOC > // centre C++ strings
detail::centre<CHAR,TRAITS,ALLOC> centre( const std::basic_string<CHAR,TRAITS,ALLOC>& str, std::size_t width )
{ return { str, width } ; }
template < typename NUM_TYPE > // centre numbers (output as narrow characters)
typename std::enable_if< std::is_arithmetic<NUM_TYPE>::value,
detail::centre<char> >::type
centre( const NUM_TYPE& number, std::size_t width )
{ return { std::to_string(number), width } ; }
template < typename NUM_TYPE > // centre numbers (output as wide characters)
typename std::enable_if< std::is_arithmetic<NUM_TYPE>::value,
detail::centre<wchar_t> >::type
wcentre( const NUM_TYPE& number, std::size_t width )
{ return { std::to_wstring(number), width } ; }
}
int main()
{
using namespace std::literals ;
std::cout << '|' << manip::centre( "abcde", 20 ) << "|\n"
<< '|' << manip::centre( "fghijk"s, 20 ) << "|\n"
<< '|' << manip::centre( "lmnopqr"s, 20 ) << "|\n"
<< '|' << manip::centre( -123.45, 20 ) << "|\n" ;
std::wcout << L'|' << manip::centre( L"jklmno", 20 ) << L"|\n"
<< L'|' << manip::centre( L"pqrstuv"s, 20 ) << L"|\n"
<< L'|' << manip::centre( L"lmnopqr"s, 20 ) << L"|\n"
<< L'|' << manip::wcentre( -123.45, 20 ) << "|\n" ;
}
|