-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcentered_string.h
98 lines (83 loc) · 2.46 KB
/
centered_string.h
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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
// Based on an answer on SO: http://stackoverflow.com/a/14861289/680359
// But modernized and genericized.
#include <string>
#include <iostream>
#include <iomanip>
#include <experimental/string_view>
namespace __detail
{
/**
* @brief Struct for centered strings.
*/
template<typename _String>
struct _Centered_string
{
static_assert(std::is_reference<_String>::value
|| std::is_pointer<_String>::value,
"String type must be pointer or reference");
_Centered_string(_String __str)
: _M_str(__str)
{ }
_String _M_str;
};
/**
* @brief Struct for centered strings.
*/
template<typename _CharT>
struct _Centered_string<const _CharT*>
{
_Centered_string(const _CharT* __str)
: _M_str(__str)
{ }
std::experimental::basic_string_view<_CharT> _M_str;
};
/**
* @brief Struct for centered strings.
*/
template<typename _CharT, typename _Traits, typename _Alloc>
struct _Centered_string<const std::basic_string<_CharT, _Traits, _Alloc>&>
{
_Centered_string(const std::basic_string<_CharT, _Traits, _Alloc>& __str)
: _M_str(__str)
{ }
std::experimental::basic_string_view<_CharT> _M_str;
};
} // namespace __detail
template<typename _CharT>
inline auto
centered(const _CharT* __str)
{
return __detail::_Centered_string<const _CharT*>(__str);
}
template<typename _CharT, typename _Traits, typename _Alloc>
inline auto
centered(const std::basic_string<_CharT, _Traits, _Alloc>& __str)
{
using __StringT = std::basic_string<_CharT, _Traits, _Alloc>;
return __detail::_Centered_string<const __StringT &>(__str);
}
template<typename _CharT, typename _Traits>
inline auto
centered(const std::experimental::basic_string_view<_CharT, _Traits>& __str)
{
using __StringT = std::experimental::basic_string_view<_CharT, _Traits>;
return __detail::_Centered_string<const __StringT &>(__str);
}
template<typename _String, typename _CharT, typename _Traits>
auto&
operator<<(std::basic_ostream<_CharT, _Traits>& __os,
const __detail::_Centered_string<_String>& __str)
{
std::streamsize __width = __os.width();
if (__width > __str._M_str.length())
{
std::streamsize __left = (__width + __str._M_str.length()) / 2;
__os.width(__left);
__os << __str._M_str;
__os.width(__width - __left);
__os << "";
}
else
__os << __str._M_str;
return __os;
}