run clang-format
This commit is contained in:
parent
4d25fc25c4
commit
492a0f3c55
|
@ -27,42 +27,42 @@ template<typename T, typename TChar, typename TCharTraits>
|
||||||
std::basic_ostream<TChar, TCharTraits> &
|
std::basic_ostream<TChar, TCharTraits> &
|
||||||
print(std::basic_ostream<TChar, TCharTraits> &stream, const T &x);
|
print(std::basic_ostream<TChar, TCharTraits> &stream, const T &x);
|
||||||
|
|
||||||
namespace detail
|
namespace detail {
|
||||||
{
|
|
||||||
// SFINAE type trait to detect whether T::const_iterator exists.
|
// SFINAE type trait to detect whether T::const_iterator exists.
|
||||||
|
|
||||||
struct sfinae_base
|
struct sfinae_base {
|
||||||
{
|
|
||||||
using yes = char;
|
using yes = char;
|
||||||
using no = yes[2];
|
using no = yes[2];
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T> struct has_const_iterator : private sfinae_base {
|
||||||
struct has_const_iterator : private sfinae_base
|
|
||||||
{
|
|
||||||
private:
|
private:
|
||||||
template <typename C> static yes &test(typename C::const_iterator *);
|
template <typename C> static yes &test(typename C::const_iterator *);
|
||||||
template <typename C> static no &test(...);
|
template <typename C> static no &test(...);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static const bool value = sizeof(test<T>(nullptr)) == sizeof(yes);
|
static const bool value = sizeof(test<T>(nullptr)) == sizeof(yes);
|
||||||
using type = T;
|
using type = T;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T> struct has_begin_end : private sfinae_base {
|
||||||
struct has_begin_end : private sfinae_base
|
|
||||||
{
|
|
||||||
private:
|
private:
|
||||||
template <typename C>
|
template <typename C>
|
||||||
static yes & f(typename std::enable_if<
|
static yes &
|
||||||
std::is_same<decltype(static_cast<typename C::const_iterator(C::*)() const>(&C::begin)),
|
f(typename std::enable_if<
|
||||||
|
std::is_same<decltype(static_cast<typename C::const_iterator (C::*)()
|
||||||
|
const>(&C::begin)),
|
||||||
typename C::const_iterator (C::*)() const>::value>::type *);
|
typename C::const_iterator (C::*)() const>::value>::type *);
|
||||||
|
|
||||||
template <typename C> static no &f(...);
|
template <typename C> static no &f(...);
|
||||||
|
|
||||||
template <typename C>
|
template <typename C>
|
||||||
static yes & g(typename std::enable_if<
|
static yes &
|
||||||
std::is_same<decltype(static_cast<typename C::const_iterator(C::*)() const>(&C::end)),
|
g(typename std::enable_if<
|
||||||
typename C::const_iterator(C::*)() const>::value, void>::type*);
|
std::is_same<decltype(static_cast<typename C::const_iterator (C::*)()
|
||||||
|
const>(&C::end)),
|
||||||
|
typename C::const_iterator (C::*)() const>::value,
|
||||||
|
void>::type *);
|
||||||
|
|
||||||
template <typename C> static no &g(...);
|
template <typename C> static no &g(...);
|
||||||
|
|
||||||
|
@ -73,60 +73,47 @@ public:
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
|
|
||||||
// Holds the delimiter values for a specific character type
|
// Holds the delimiter values for a specific character type
|
||||||
|
|
||||||
template <typename TChar>
|
template <typename TChar> struct delimiters_values {
|
||||||
struct delimiters_values
|
|
||||||
{
|
|
||||||
using char_type = TChar;
|
using char_type = TChar;
|
||||||
const char_type *prefix;
|
const char_type *prefix;
|
||||||
const char_type *delimiter;
|
const char_type *delimiter;
|
||||||
const char_type *postfix;
|
const char_type *postfix;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Defines the delimiter values for a specific container and character type
|
// Defines the delimiter values for a specific container and character type
|
||||||
|
|
||||||
template <typename T, typename TChar>
|
template <typename T, typename TChar> struct delimiters {
|
||||||
struct delimiters
|
|
||||||
{
|
|
||||||
using type = delimiters_values<TChar>;
|
using type = delimiters_values<TChar>;
|
||||||
static const type values;
|
static const type values;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Functor to pretty_print containers. You can use this directly if you want
|
// Functor to pretty_print containers. You can use this directly if you want
|
||||||
// to specificy a non-default delimiters type. The pretty_printing logic can
|
// to specificy a non-default delimiters type. The pretty_printing logic can
|
||||||
// be customized by specializing the nested template.
|
// be customized by specializing the nested template.
|
||||||
|
|
||||||
template <typename T,
|
template <typename T, typename TChar = char,
|
||||||
typename TChar = char,
|
|
||||||
typename TCharTraits = ::std::char_traits<TChar>,
|
typename TCharTraits = ::std::char_traits<TChar>,
|
||||||
typename TDelimiters = delimiters<T, TChar>>
|
typename TDelimiters = delimiters<T, TChar>>
|
||||||
struct pretty_print_container_helper
|
struct pretty_print_container_helper {
|
||||||
{
|
|
||||||
using delimiters_type = TDelimiters;
|
using delimiters_type = TDelimiters;
|
||||||
using ostream_type = std::basic_ostream<TChar, TCharTraits>;
|
using ostream_type = std::basic_ostream<TChar, TCharTraits>;
|
||||||
|
|
||||||
template <typename U>
|
template <typename U> struct pretty_printer {
|
||||||
struct pretty_printer
|
static void pretty_print_body(const U &c, ostream_type &stream) {
|
||||||
{
|
|
||||||
static void pretty_print_body(const U & c, ostream_type & stream)
|
|
||||||
{
|
|
||||||
using std::begin;
|
using std::begin;
|
||||||
using std::end;
|
using std::end;
|
||||||
|
|
||||||
auto it = begin(c);
|
auto it = begin(c);
|
||||||
const auto the_end = end(c);
|
const auto the_end = end(c);
|
||||||
|
|
||||||
if (it != the_end)
|
if (it != the_end) {
|
||||||
{
|
for (;;) {
|
||||||
for ( ; ; )
|
|
||||||
{
|
|
||||||
::soi::print(stream, *it);
|
::soi::print(stream, *it);
|
||||||
|
|
||||||
if (++it == the_end) break;
|
if (++it == the_end)
|
||||||
|
break;
|
||||||
|
|
||||||
if (delimiters_type::values.delimiter != NULL)
|
if (delimiters_type::values.delimiter != NULL)
|
||||||
::soi::print(stream, delimiters_type::values.delimiter);
|
::soi::print(stream, delimiters_type::values.delimiter);
|
||||||
|
@ -135,12 +122,9 @@ struct pretty_print_container_helper
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pretty_print_container_helper(const T & container)
|
pretty_print_container_helper(const T &container) : container_(container) {}
|
||||||
: container_(container)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
inline void operator()(ostream_type & stream) const
|
inline void operator()(ostream_type &stream) const {
|
||||||
{
|
|
||||||
if (delimiters_type::values.prefix != NULL)
|
if (delimiters_type::values.prefix != NULL)
|
||||||
::soi::print(stream, delimiters_type::values.prefix);
|
::soi::print(stream, delimiters_type::values.prefix);
|
||||||
|
|
||||||
|
@ -156,53 +140,70 @@ private:
|
||||||
|
|
||||||
// Specialization for pairs
|
// Specialization for pairs
|
||||||
|
|
||||||
template <typename T, typename TChar, typename TCharTraits, typename TDelimiters>
|
template <typename T, typename TChar, typename TCharTraits,
|
||||||
|
typename TDelimiters>
|
||||||
template <typename T1, typename T2>
|
template <typename T1, typename T2>
|
||||||
struct pretty_print_container_helper<T, TChar, TCharTraits, TDelimiters>::pretty_printer<std::pair<T1, T2>>
|
struct pretty_print_container_helper<
|
||||||
{
|
T, TChar, TCharTraits, TDelimiters>::pretty_printer<std::pair<T1, T2>> {
|
||||||
using ostream_type = typename pretty_print_container_helper<T, TChar, TCharTraits, TDelimiters>::ostream_type;
|
using ostream_type =
|
||||||
|
typename pretty_print_container_helper<T, TChar, TCharTraits,
|
||||||
|
TDelimiters>::ostream_type;
|
||||||
|
|
||||||
static void pretty_print_body(const std::pair<T1, T2> & c, ostream_type & stream)
|
static void pretty_print_body(const std::pair<T1, T2> &c,
|
||||||
{
|
ostream_type &stream) {
|
||||||
::soi::print(stream, c.first);
|
::soi::print(stream, c.first);
|
||||||
if (pretty_print_container_helper<T, TChar, TCharTraits, TDelimiters>::delimiters_type::values.delimiter != NULL)
|
if (pretty_print_container_helper<T, TChar, TCharTraits,
|
||||||
::soi::print(stream, pretty_print_container_helper<T, TChar, TCharTraits, TDelimiters>::delimiters_type::values.delimiter);
|
TDelimiters>::delimiters_type::values
|
||||||
|
.delimiter != NULL)
|
||||||
|
::soi::print(
|
||||||
|
stream,
|
||||||
|
pretty_print_container_helper<T, TChar, TCharTraits,
|
||||||
|
TDelimiters>::delimiters_type::values
|
||||||
|
.delimiter);
|
||||||
::soi::print(stream, c.second);
|
::soi::print(stream, c.second);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Specialization for tuples
|
// Specialization for tuples
|
||||||
|
|
||||||
template <typename T, typename TChar, typename TCharTraits, typename TDelimiters>
|
template <typename T, typename TChar, typename TCharTraits,
|
||||||
|
typename TDelimiters>
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
struct pretty_print_container_helper<T, TChar, TCharTraits, TDelimiters>::pretty_printer<std::tuple<Args...>>
|
struct pretty_print_container_helper<
|
||||||
{
|
T, TChar, TCharTraits, TDelimiters>::pretty_printer<std::tuple<Args...>> {
|
||||||
using ostream_type = typename pretty_print_container_helper<T, TChar, TCharTraits, TDelimiters>::ostream_type;
|
using ostream_type =
|
||||||
|
typename pretty_print_container_helper<T, TChar, TCharTraits,
|
||||||
|
TDelimiters>::ostream_type;
|
||||||
using element_type = std::tuple<Args...>;
|
using element_type = std::tuple<Args...>;
|
||||||
|
|
||||||
template <std::size_t I> struct Int {};
|
template <std::size_t I> struct Int {};
|
||||||
|
|
||||||
static void pretty_print_body(const element_type & c, ostream_type & stream)
|
static void pretty_print_body(const element_type &c, ostream_type &stream) {
|
||||||
{
|
|
||||||
tuple_pretty_print(c, stream, Int<0>());
|
tuple_pretty_print(c, stream, Int<0>());
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tuple_pretty_print(const element_type &, ostream_type &, Int<sizeof...(Args)>)
|
static void tuple_pretty_print(const element_type &, ostream_type &,
|
||||||
{
|
Int<sizeof...(Args)>) {}
|
||||||
}
|
|
||||||
|
|
||||||
static void tuple_pretty_print(const element_type & c, ostream_type & stream,
|
static void
|
||||||
typename std::conditional<sizeof...(Args) != 0, Int<0>, std::nullptr_t>::type)
|
tuple_pretty_print(const element_type &c, ostream_type &stream,
|
||||||
{
|
typename std::conditional<sizeof...(Args) != 0, Int<0>,
|
||||||
|
std::nullptr_t>::type) {
|
||||||
::soi::print(stream, std::get<0>(c));
|
::soi::print(stream, std::get<0>(c));
|
||||||
tuple_pretty_print(c, stream, Int<1>());
|
tuple_pretty_print(c, stream, Int<1>());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <std::size_t N>
|
template <std::size_t N>
|
||||||
static void tuple_pretty_print(const element_type & c, ostream_type & stream, Int<N>)
|
static void tuple_pretty_print(const element_type &c, ostream_type &stream,
|
||||||
{
|
Int<N>) {
|
||||||
if (pretty_print_container_helper<T, TChar, TCharTraits, TDelimiters>::delimiters_type::values.delimiter != NULL)
|
if (pretty_print_container_helper<T, TChar, TCharTraits,
|
||||||
::soi::print(stream, pretty_print_container_helper<T, TChar, TCharTraits, TDelimiters>::delimiters_type::values.delimiter);
|
TDelimiters>::delimiters_type::values
|
||||||
|
.delimiter != NULL)
|
||||||
|
::soi::print(
|
||||||
|
stream,
|
||||||
|
pretty_print_container_helper<T, TChar, TCharTraits,
|
||||||
|
TDelimiters>::delimiters_type::values
|
||||||
|
.delimiter);
|
||||||
|
|
||||||
::soi::print(stream, std::get<N>(c));
|
::soi::print(stream, std::get<N>(c));
|
||||||
|
|
||||||
|
@ -212,20 +213,22 @@ struct pretty_print_container_helper<T, TChar, TCharTraits, TDelimiters>::pretty
|
||||||
|
|
||||||
// Pretty_Prints a pretty_print_container_helper to the specified stream.
|
// Pretty_Prints a pretty_print_container_helper to the specified stream.
|
||||||
|
|
||||||
template<typename T, typename TChar, typename TCharTraits, typename TDelimiters>
|
template <typename T, typename TChar, typename TCharTraits,
|
||||||
inline std::basic_ostream<TChar, TCharTraits> & pretty_print(
|
typename TDelimiters>
|
||||||
std::basic_ostream<TChar, TCharTraits> & stream,
|
inline std::basic_ostream<TChar, TCharTraits> &
|
||||||
const pretty_print_container_helper<T, TChar, TCharTraits, TDelimiters> & helper)
|
pretty_print(std::basic_ostream<TChar, TCharTraits> &stream,
|
||||||
{
|
const pretty_print_container_helper<T, TChar, TCharTraits,
|
||||||
|
TDelimiters> &helper) {
|
||||||
helper(stream);
|
helper(stream);
|
||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Basic is_container template; specialize to derive from std::true_type for all
|
||||||
// Basic is_container template; specialize to derive from std::true_type for all desired container types
|
// desired container types
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct is_container : public std::integral_constant<bool,
|
struct is_container
|
||||||
|
: public std::integral_constant<bool,
|
||||||
detail::has_const_iterator<T>::value &&
|
detail::has_const_iterator<T>::value &&
|
||||||
detail::has_begin_end<T>::beg_value &&
|
detail::has_begin_end<T>::beg_value &&
|
||||||
detail::has_begin_end<T>::end_value> {};
|
detail::has_begin_end<T>::end_value> {};
|
||||||
|
@ -233,11 +236,9 @@ struct is_container : public std::integral_constant<bool,
|
||||||
template <typename T, std::size_t N>
|
template <typename T, std::size_t N>
|
||||||
struct is_container<T[N]> : std::true_type {};
|
struct is_container<T[N]> : std::true_type {};
|
||||||
|
|
||||||
template <std::size_t N>
|
template <std::size_t N> struct is_container<char[N]> : std::false_type {};
|
||||||
struct is_container<char[N]> : std::false_type { };
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T> struct is_container<std::valarray<T>> : std::true_type {};
|
||||||
struct is_container<std::valarray<T>> : std::true_type { };
|
|
||||||
|
|
||||||
template <typename T1, typename T2>
|
template <typename T1, typename T2>
|
||||||
struct is_container<std::pair<T1, T2>> : std::true_type {};
|
struct is_container<std::pair<T1, T2>> : std::true_type {};
|
||||||
|
@ -245,131 +246,183 @@ struct is_container<std::pair<T1, T2>> : std::true_type { };
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
struct is_container<std::tuple<Args...>> : std::true_type {};
|
struct is_container<std::tuple<Args...>> : std::true_type {};
|
||||||
|
|
||||||
|
|
||||||
// Default delimiters
|
// Default delimiters
|
||||||
|
|
||||||
template <typename T> struct delimiters<T, char> { static const delimiters_values<char> values; };
|
template <typename T> struct delimiters<T, char> {
|
||||||
template <typename T> const delimiters_values<char> delimiters<T, char>::values = { "[", ", ", "]" };
|
static const delimiters_values<char> values;
|
||||||
template <typename T> struct delimiters<T, wchar_t> { static const delimiters_values<wchar_t> values; };
|
};
|
||||||
template <typename T> const delimiters_values<wchar_t> delimiters<T, wchar_t>::values = { L"[", L", ", L"]" };
|
template <typename T>
|
||||||
|
const delimiters_values<char> delimiters<T, char>::values = {"[", ", ", "]"};
|
||||||
|
template <typename T> struct delimiters<T, wchar_t> {
|
||||||
|
static const delimiters_values<wchar_t> values;
|
||||||
|
};
|
||||||
|
template <typename T>
|
||||||
|
const delimiters_values<wchar_t> delimiters<T, wchar_t>::values = {L"[", L", ",
|
||||||
|
L"]"};
|
||||||
|
|
||||||
// Delimiters for (multi)set and unordered_(multi)set
|
// Delimiters for (multi)set and unordered_(multi)set
|
||||||
|
|
||||||
template <typename T, typename TComp, typename TAllocator>
|
template <typename T, typename TComp, typename TAllocator>
|
||||||
struct delimiters< ::std::set<T, TComp, TAllocator>, char> { static const delimiters_values<char> values; };
|
struct delimiters<::std::set<T, TComp, TAllocator>, char> {
|
||||||
|
static const delimiters_values<char> values;
|
||||||
|
};
|
||||||
|
|
||||||
template <typename T, typename TComp, typename TAllocator>
|
template <typename T, typename TComp, typename TAllocator>
|
||||||
const delimiters_values<char> delimiters< ::std::set<T, TComp, TAllocator>, char>::values = { "{", ", ", "}" };
|
const delimiters_values<char>
|
||||||
|
delimiters<::std::set<T, TComp, TAllocator>, char>::values = {"{", ", ",
|
||||||
|
"}"};
|
||||||
|
|
||||||
template <typename T, typename TComp, typename TAllocator>
|
template <typename T, typename TComp, typename TAllocator>
|
||||||
struct delimiters< ::std::set<T, TComp, TAllocator>, wchar_t> { static const delimiters_values<wchar_t> values; };
|
struct delimiters<::std::set<T, TComp, TAllocator>, wchar_t> {
|
||||||
|
static const delimiters_values<wchar_t> values;
|
||||||
|
};
|
||||||
|
|
||||||
template <typename T, typename TComp, typename TAllocator>
|
template <typename T, typename TComp, typename TAllocator>
|
||||||
const delimiters_values<wchar_t> delimiters< ::std::set<T, TComp, TAllocator>, wchar_t>::values = { L"{", L", ", L"}" };
|
const delimiters_values<wchar_t>
|
||||||
|
delimiters<::std::set<T, TComp, TAllocator>, wchar_t>::values = {
|
||||||
|
L"{", L", ", L"}"};
|
||||||
|
|
||||||
template <typename T, typename TComp, typename TAllocator>
|
template <typename T, typename TComp, typename TAllocator>
|
||||||
struct delimiters< ::std::multiset<T, TComp, TAllocator>, char> { static const delimiters_values<char> values; };
|
struct delimiters<::std::multiset<T, TComp, TAllocator>, char> {
|
||||||
|
static const delimiters_values<char> values;
|
||||||
|
};
|
||||||
|
|
||||||
template <typename T, typename TComp, typename TAllocator>
|
template <typename T, typename TComp, typename TAllocator>
|
||||||
const delimiters_values<char> delimiters< ::std::multiset<T, TComp, TAllocator>, char>::values = { "{", ", ", "}" };
|
const delimiters_values<char> delimiters<::std::multiset<T, TComp, TAllocator>,
|
||||||
|
char>::values = {"{", ", ", "}"};
|
||||||
|
|
||||||
template <typename T, typename TComp, typename TAllocator>
|
template <typename T, typename TComp, typename TAllocator>
|
||||||
struct delimiters< ::std::multiset<T, TComp, TAllocator>, wchar_t> { static const delimiters_values<wchar_t> values; };
|
struct delimiters<::std::multiset<T, TComp, TAllocator>, wchar_t> {
|
||||||
|
static const delimiters_values<wchar_t> values;
|
||||||
|
};
|
||||||
|
|
||||||
template <typename T, typename TComp, typename TAllocator>
|
template <typename T, typename TComp, typename TAllocator>
|
||||||
const delimiters_values<wchar_t> delimiters< ::std::multiset<T, TComp, TAllocator>, wchar_t>::values = { L"{", L", ", L"}" };
|
const delimiters_values<wchar_t>
|
||||||
|
delimiters<::std::multiset<T, TComp, TAllocator>, wchar_t>::values = {
|
||||||
|
L"{", L", ", L"}"};
|
||||||
|
|
||||||
template <typename T, typename THash, typename TEqual, typename TAllocator>
|
template <typename T, typename THash, typename TEqual, typename TAllocator>
|
||||||
struct delimiters< ::std::unordered_set<T, THash, TEqual, TAllocator>, char> { static const delimiters_values<char> values; };
|
struct delimiters<::std::unordered_set<T, THash, TEqual, TAllocator>, char> {
|
||||||
|
static const delimiters_values<char> values;
|
||||||
|
};
|
||||||
|
|
||||||
template <typename T, typename THash, typename TEqual, typename TAllocator>
|
template <typename T, typename THash, typename TEqual, typename TAllocator>
|
||||||
const delimiters_values<char> delimiters< ::std::unordered_set<T, THash, TEqual, TAllocator>, char>::values = { "{", ", ", "}" };
|
const delimiters_values<char> delimiters<
|
||||||
|
::std::unordered_set<T, THash, TEqual, TAllocator>, char>::values = {
|
||||||
|
"{", ", ", "}"};
|
||||||
|
|
||||||
template <typename T, typename THash, typename TEqual, typename TAllocator>
|
template <typename T, typename THash, typename TEqual, typename TAllocator>
|
||||||
struct delimiters< ::std::unordered_set<T, THash, TEqual, TAllocator>, wchar_t> { static const delimiters_values<wchar_t> values; };
|
struct delimiters<::std::unordered_set<T, THash, TEqual, TAllocator>, wchar_t> {
|
||||||
|
static const delimiters_values<wchar_t> values;
|
||||||
|
};
|
||||||
|
|
||||||
template <typename T, typename THash, typename TEqual, typename TAllocator>
|
template <typename T, typename THash, typename TEqual, typename TAllocator>
|
||||||
const delimiters_values<wchar_t> delimiters< ::std::unordered_set<T, THash, TEqual, TAllocator>, wchar_t>::values = { L"{", L", ", L"}" };
|
const delimiters_values<wchar_t> delimiters<
|
||||||
|
::std::unordered_set<T, THash, TEqual, TAllocator>, wchar_t>::values = {
|
||||||
|
L"{", L", ", L"}"};
|
||||||
|
|
||||||
template <typename T, typename THash, typename TEqual, typename TAllocator>
|
template <typename T, typename THash, typename TEqual, typename TAllocator>
|
||||||
struct delimiters< ::std::unordered_multiset<T, THash, TEqual, TAllocator>, char> { static const delimiters_values<char> values; };
|
struct delimiters<::std::unordered_multiset<T, THash, TEqual, TAllocator>,
|
||||||
|
char> {
|
||||||
|
static const delimiters_values<char> values;
|
||||||
|
};
|
||||||
|
|
||||||
template <typename T, typename THash, typename TEqual, typename TAllocator>
|
template <typename T, typename THash, typename TEqual, typename TAllocator>
|
||||||
const delimiters_values<char> delimiters< ::std::unordered_multiset<T, THash, TEqual, TAllocator>, char>::values = { "{", ", ", "}" };
|
const delimiters_values<char> delimiters<
|
||||||
|
::std::unordered_multiset<T, THash, TEqual, TAllocator>, char>::values = {
|
||||||
|
"{", ", ", "}"};
|
||||||
|
|
||||||
template <typename T, typename THash, typename TEqual, typename TAllocator>
|
template <typename T, typename THash, typename TEqual, typename TAllocator>
|
||||||
struct delimiters< ::std::unordered_multiset<T, THash, TEqual, TAllocator>, wchar_t> { static const delimiters_values<wchar_t> values; };
|
struct delimiters<::std::unordered_multiset<T, THash, TEqual, TAllocator>,
|
||||||
|
wchar_t> {
|
||||||
|
static const delimiters_values<wchar_t> values;
|
||||||
|
};
|
||||||
|
|
||||||
template <typename T, typename THash, typename TEqual, typename TAllocator>
|
template <typename T, typename THash, typename TEqual, typename TAllocator>
|
||||||
const delimiters_values<wchar_t> delimiters< ::std::unordered_multiset<T, THash, TEqual, TAllocator>, wchar_t>::values = { L"{", L", ", L"}" };
|
const delimiters_values<wchar_t>
|
||||||
|
delimiters<::std::unordered_multiset<T, THash, TEqual, TAllocator>,
|
||||||
|
wchar_t>::values = {L"{", L", ", L"}"};
|
||||||
|
|
||||||
// Delimiters for pair and tuple
|
// Delimiters for pair and tuple
|
||||||
|
|
||||||
template <typename T1, typename T2> struct delimiters<std::pair<T1, T2>, char> { static const delimiters_values<char> values; };
|
template <typename T1, typename T2> struct delimiters<std::pair<T1, T2>, char> {
|
||||||
template <typename T1, typename T2> const delimiters_values<char> delimiters<std::pair<T1, T2>, char>::values = { "(", ", ", ")" };
|
static const delimiters_values<char> values;
|
||||||
template <typename T1, typename T2> struct delimiters< ::std::pair<T1, T2>, wchar_t> { static const delimiters_values<wchar_t> values; };
|
};
|
||||||
template <typename T1, typename T2> const delimiters_values<wchar_t> delimiters< ::std::pair<T1, T2>, wchar_t>::values = { L"(", L", ", L")" };
|
template <typename T1, typename T2>
|
||||||
|
const delimiters_values<char> delimiters<std::pair<T1, T2>, char>::values = {
|
||||||
template <typename ...Args> struct delimiters<std::tuple<Args...>, char> { static const delimiters_values<char> values; };
|
"(", ", ", ")"};
|
||||||
template <typename ...Args> const delimiters_values<char> delimiters<std::tuple<Args...>, char>::values = { "(", ", ", ")" };
|
template <typename T1, typename T2>
|
||||||
template <typename ...Args> struct delimiters< ::std::tuple<Args...>, wchar_t> { static const delimiters_values<wchar_t> values; };
|
struct delimiters<::std::pair<T1, T2>, wchar_t> {
|
||||||
template <typename ...Args> const delimiters_values<wchar_t> delimiters< ::std::tuple<Args...>, wchar_t>::values = { L"(", L", ", L")" };
|
static const delimiters_values<wchar_t> values;
|
||||||
|
};
|
||||||
|
template <typename T1, typename T2>
|
||||||
|
const delimiters_values<wchar_t>
|
||||||
|
delimiters<::std::pair<T1, T2>, wchar_t>::values = {L"(", L", ", L")"};
|
||||||
|
|
||||||
|
template <typename... Args> struct delimiters<std::tuple<Args...>, char> {
|
||||||
|
static const delimiters_values<char> values;
|
||||||
|
};
|
||||||
|
template <typename... Args>
|
||||||
|
const delimiters_values<char> delimiters<std::tuple<Args...>, char>::values = {
|
||||||
|
"(", ", ", ")"};
|
||||||
|
template <typename... Args> struct delimiters<::std::tuple<Args...>, wchar_t> {
|
||||||
|
static const delimiters_values<wchar_t> values;
|
||||||
|
};
|
||||||
|
template <typename... Args>
|
||||||
|
const delimiters_values<wchar_t>
|
||||||
|
delimiters<::std::tuple<Args...>, wchar_t>::values = {L"(", L", ", L")"};
|
||||||
|
|
||||||
// Type-erasing helper class for easy use of custom delimiters.
|
// Type-erasing helper class for easy use of custom delimiters.
|
||||||
// Requires TCharTraits = std::char_traits<TChar> and TChar = char or wchar_t, and MyDelims needs to be defined for TChar.
|
// Requires TCharTraits = std::char_traits<TChar> and TChar = char or wchar_t,
|
||||||
// Usage: "cout << pretty_pretty_print::custom_delims<MyDelims>(x)".
|
// and MyDelims needs to be defined for TChar. Usage: "cout <<
|
||||||
|
// pretty_pretty_print::custom_delims<MyDelims>(x)".
|
||||||
|
|
||||||
struct custom_delims_base
|
struct custom_delims_base {
|
||||||
{
|
|
||||||
virtual ~custom_delims_base() {}
|
virtual ~custom_delims_base() {}
|
||||||
virtual std::ostream &stream(::std::ostream &) = 0;
|
virtual std::ostream &stream(::std::ostream &) = 0;
|
||||||
virtual std::wostream &stream(::std::wostream &) = 0;
|
virtual std::wostream &stream(::std::wostream &) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, typename Delims>
|
template <typename T, typename Delims>
|
||||||
struct custom_delims_wrapper : custom_delims_base
|
struct custom_delims_wrapper : custom_delims_base {
|
||||||
{
|
|
||||||
custom_delims_wrapper(const T &t_) : t(t_) {}
|
custom_delims_wrapper(const T &t_) : t(t_) {}
|
||||||
|
|
||||||
std::ostream & stream(std::ostream & s)
|
std::ostream &stream(std::ostream &s) {
|
||||||
{
|
return pretty_print(
|
||||||
return pretty_print(s, pretty_print_container_helper<T, char, std::char_traits<char>, Delims>(t));
|
s,
|
||||||
|
pretty_print_container_helper<T, char, std::char_traits<char>, Delims>(
|
||||||
|
t));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::wostream & stream(std::wostream & s)
|
std::wostream &stream(std::wostream &s) {
|
||||||
{
|
return pretty_print(
|
||||||
return pretty_print(s, pretty_print_container_helper<T, wchar_t, std::char_traits<wchar_t>, Delims>(t));
|
s, pretty_print_container_helper<T, wchar_t, std::char_traits<wchar_t>,
|
||||||
|
Delims>(t));
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const T &t;
|
const T &t;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Delims>
|
template <typename Delims> struct custom_delims {
|
||||||
struct custom_delims
|
|
||||||
{
|
|
||||||
template <typename Container>
|
template <typename Container>
|
||||||
custom_delims(const Container & c) : base(new custom_delims_wrapper<Container, Delims>(c)) { }
|
custom_delims(const Container &c)
|
||||||
|
: base(new custom_delims_wrapper<Container, Delims>(c)) {}
|
||||||
|
|
||||||
std::unique_ptr<custom_delims_base> base;
|
std::unique_ptr<custom_delims_base> base;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename TChar, typename TCharTraits, typename Delims>
|
template <typename TChar, typename TCharTraits, typename Delims>
|
||||||
inline std::basic_ostream<TChar, TCharTraits> & pretty_print(std::basic_ostream<TChar, TCharTraits> & s, const custom_delims<Delims> & p)
|
inline std::basic_ostream<TChar, TCharTraits> &
|
||||||
{
|
pretty_print(std::basic_ostream<TChar, TCharTraits> &s,
|
||||||
|
const custom_delims<Delims> &p) {
|
||||||
return p.base->stream(s);
|
return p.base->stream(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// A wrapper for a C-style array given as pointer-plus-size.
|
// A wrapper for a C-style array given as pointer-plus-size.
|
||||||
// Usage: std::cout << pretty_pretty_print_array(arr, n) << std::endl;
|
// Usage: std::cout << pretty_pretty_print_array(arr, n) << std::endl;
|
||||||
|
|
||||||
template<typename T>
|
template <typename T> struct array_wrapper_n {
|
||||||
struct array_wrapper_n
|
|
||||||
{
|
|
||||||
typedef const T *const_iterator;
|
typedef const T *const_iterator;
|
||||||
typedef T value_type;
|
typedef T value_type;
|
||||||
|
|
||||||
|
@ -382,27 +435,20 @@ private:
|
||||||
size_t _n;
|
size_t _n;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// A wrapper for hash-table based containers that offer local iterators to each
|
||||||
|
// bucket. Usage: std::cout << bucket_pretty_print(m, 4) << std::endl;
|
||||||
|
// (Pretty_Prints bucket 5 of container m.)
|
||||||
|
|
||||||
// A wrapper for hash-table based containers that offer local iterators to each bucket.
|
template <typename T> struct bucket_pretty_print_wrapper {
|
||||||
// Usage: std::cout << bucket_pretty_print(m, 4) << std::endl; (Pretty_Prints bucket 5 of container m.)
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct bucket_pretty_print_wrapper
|
|
||||||
{
|
|
||||||
typedef typename T::const_local_iterator const_iterator;
|
typedef typename T::const_local_iterator const_iterator;
|
||||||
typedef typename T::size_type size_type;
|
typedef typename T::size_type size_type;
|
||||||
|
|
||||||
const_iterator begin() const
|
const_iterator begin() const { return m_map.cbegin(n); }
|
||||||
{
|
|
||||||
return m_map.cbegin(n);
|
|
||||||
}
|
|
||||||
|
|
||||||
const_iterator end() const
|
const_iterator end() const { return m_map.cend(n); }
|
||||||
{
|
|
||||||
return m_map.cend(n);
|
|
||||||
}
|
|
||||||
|
|
||||||
bucket_pretty_print_wrapper(const T & m, size_type bucket) : m_map(m), n(bucket) { }
|
bucket_pretty_print_wrapper(const T &m, size_type bucket)
|
||||||
|
: m_map(m), n(bucket) {}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const T &m_map;
|
const T &m_map;
|
||||||
|
@ -411,12 +457,12 @@ private:
|
||||||
|
|
||||||
} // namespace soi
|
} // namespace soi
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// Global accessor functions for the convenience wrappers
|
// Global accessor functions for the convenience wrappers
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline pretty_pretty_print::array_wrapper_n<T> pretty_pretty_print_array(const T * const a, size_t n)
|
inline pretty_pretty_print::array_wrapper_n<T> pretty_pretty_print_array(const T
|
||||||
|
* const a, size_t n)
|
||||||
{
|
{
|
||||||
return pretty_pretty_print::array_wrapper_n<T>(a, n);
|
return pretty_pretty_print::array_wrapper_n<T>(a, n);
|
||||||
}
|
}
|
||||||
|
@ -433,18 +479,18 @@ return pretty_pretty_print::bucket_pretty_print_wrapper<T>(m, n);
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace soi
|
namespace soi {
|
||||||
{
|
|
||||||
// Pretty_Prints a container to the stream using default delimiters
|
// Pretty_Prints a container to the stream using default delimiters
|
||||||
|
|
||||||
template <typename T, typename TChar, typename TCharTraits>
|
template <typename T, typename TChar, typename TCharTraits>
|
||||||
inline typename std::enable_if<::soi::is_container<T>::value,
|
inline typename std::enable_if<::soi::is_container<T>::value,
|
||||||
std::basic_ostream<TChar, TCharTraits> &>::type
|
std::basic_ostream<TChar, TCharTraits> &>::type
|
||||||
pretty_print(std::basic_ostream<TChar, TCharTraits> & stream, const T & container)
|
pretty_print(std::basic_ostream<TChar, TCharTraits> &stream,
|
||||||
{
|
const T &container) {
|
||||||
return ::soi::print(stream, ::soi::pretty_print_container_helper<T, TChar, TCharTraits>(container));
|
return ::soi::print(
|
||||||
|
stream,
|
||||||
|
::soi::pretty_print_container_helper<T, TChar, TCharTraits>(container));
|
||||||
}
|
}
|
||||||
}
|
} // namespace soi
|
||||||
|
|
||||||
|
|
||||||
#endif // SOI_PRETTY_PRETTY_PRINT
|
#endif // SOI_PRETTY_PRETTY_PRINT
|
||||||
|
|
|
@ -11,11 +11,11 @@
|
||||||
#define SOI_DBG
|
#define SOI_DBG
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <stdexcept>
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <ostream>
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <ostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
|
#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
@ -68,15 +68,12 @@ public:
|
||||||
typedef const char *const_iterator;
|
typedef const char *const_iterator;
|
||||||
|
|
||||||
template <std::size_t N>
|
template <std::size_t N>
|
||||||
CONSTEXPR11_TN static_string(const char(&a)[N]) NOEXCEPT_TN
|
CONSTEXPR11_TN static_string(const char (&a)[N]) NOEXCEPT_TN : p_(a),
|
||||||
: p_(a)
|
sz_(N - 1) {}
|
||||||
, sz_(N-1)
|
|
||||||
{}
|
|
||||||
|
|
||||||
CONSTEXPR11_TN static_string(const char *p, std::size_t N) NOEXCEPT_TN
|
CONSTEXPR11_TN static_string(const char *p, std::size_t N) NOEXCEPT_TN
|
||||||
: p_(p)
|
: p_(p),
|
||||||
, sz_(N)
|
sz_(N) {}
|
||||||
{}
|
|
||||||
|
|
||||||
CONSTEXPR11_TN const char *data() const NOEXCEPT_TN { return p_; }
|
CONSTEXPR11_TN const char *data() const NOEXCEPT_TN { return p_; }
|
||||||
CONSTEXPR11_TN std::size_t size() const NOEXCEPT_TN { return sz_; }
|
CONSTEXPR11_TN std::size_t size() const NOEXCEPT_TN { return sz_; }
|
||||||
|
@ -84,24 +81,16 @@ public:
|
||||||
CONSTEXPR11_TN const_iterator begin() const NOEXCEPT_TN { return p_; }
|
CONSTEXPR11_TN const_iterator begin() const NOEXCEPT_TN { return p_; }
|
||||||
CONSTEXPR11_TN const_iterator end() const NOEXCEPT_TN { return p_ + sz_; }
|
CONSTEXPR11_TN const_iterator end() const NOEXCEPT_TN { return p_ + sz_; }
|
||||||
|
|
||||||
CONSTEXPR11_TN char operator[](std::size_t n) const
|
CONSTEXPR11_TN char operator[](std::size_t n) const {
|
||||||
{
|
|
||||||
return n < sz_ ? p_[n] : throw std::out_of_range("static_string");
|
return n < sz_ ? p_[n] : throw std::out_of_range("static_string");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
inline
|
inline std::ostream &operator<<(std::ostream &os, static_string const &s) {
|
||||||
std::ostream&
|
|
||||||
operator<<(std::ostream& os, static_string const& s)
|
|
||||||
{
|
|
||||||
return os.write(s.data(), s.size());
|
return os.write(s.data(), s.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T> CONSTEXPR14_TN static_string type_name() {
|
||||||
CONSTEXPR14_TN
|
|
||||||
static_string
|
|
||||||
type_name()
|
|
||||||
{
|
|
||||||
const int k = sizeof("constexpr soi::detail:: T") / sizeof(char);
|
const int k = sizeof("constexpr soi::detail:: T") / sizeof(char);
|
||||||
#ifdef __clang__
|
#ifdef __clang__
|
||||||
static_string p = __PRETTY_FUNCTION__;
|
static_string p = __PRETTY_FUNCTION__;
|
||||||
|
@ -120,24 +109,21 @@ type_name()
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr bool is_prefix_of(char const *suffix, char const *s) {
|
constexpr bool is_prefix_of(char const *suffix, char const *s) {
|
||||||
return suffix[0]=='\0' || (suffix[0] == s[0] && is_prefix_of(suffix + 1, s + 1));
|
return suffix[0] == '\0' ||
|
||||||
|
(suffix[0] == s[0] && is_prefix_of(suffix + 1, s + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
static char const *const type_string = "string";
|
static char const *const type_string = "string";
|
||||||
|
|
||||||
template <class T>
|
template <class T> CONSTEXPR14_TN static_string sanitized_type_name() {
|
||||||
CONSTEXPR14_TN
|
|
||||||
static_string
|
|
||||||
sanitized_type_name() {
|
|
||||||
CONSTEXPR14_TN static_string t = type_name<T>();
|
CONSTEXPR14_TN static_string t = type_name<T>();
|
||||||
CONSTEXPR14_TN std::size_t offset =
|
CONSTEXPR14_TN std::size_t offset =
|
||||||
is_prefix_of("std::__debug::", t.data()) ? sizeof("std::__debug::")-1 :
|
is_prefix_of("std::__debug::", t.data())
|
||||||
is_prefix_of("std::", t.data()) ? sizeof("std::")-1 :
|
? sizeof("std::__debug::") - 1
|
||||||
0;
|
: is_prefix_of("std::", t.data()) ? sizeof("std::") - 1 : 0;
|
||||||
return
|
return is_prefix_of("std::__cxx11::basic_string<char>", t.data())
|
||||||
is_prefix_of("std::__cxx11::basic_string<char>", t.data()) ?
|
? static_string(type_string, sizeof(type_string) - 2)
|
||||||
static_string(type_string, sizeof(type_string)-2) :
|
: static_string(t.data() + offset, t.size() - offset);
|
||||||
static_string(t.data()+offset, t.size()-offset);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
@ -199,70 +185,51 @@ void dbg_init(bool with_colors) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void dbg_init() {
|
void dbg_init() { dbg_init(are_colors_enabled()); }
|
||||||
dbg_init(are_colors_enabled());
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// printer
|
// printer
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
T&& dbg_print(T&& value,
|
T &&dbg_print(T &&value, static_string const &type, char const *file, int line,
|
||||||
static_string const& type,
|
char const *function_name, char const *expression) {
|
||||||
char const* file,
|
|
||||||
int line,
|
|
||||||
char const* function_name,
|
|
||||||
char const* expression) {
|
|
||||||
const T &ref = value;
|
const T &ref = value;
|
||||||
std::stringstream value_buffer; // avoid nesting of dbg macros within print functinos
|
std::stringstream
|
||||||
|
value_buffer; // avoid nesting of dbg macros within print functinos
|
||||||
soi::print(value_buffer, ref);
|
soi::print(value_buffer, ref);
|
||||||
|
|
||||||
std::cerr << ANSI_DEBUG
|
std::cerr << ANSI_DEBUG << "[" << file << ":" << line << " (" << function_name
|
||||||
<< "[" << file << ":" << line
|
<< ")] " << ANSI_RESET << ANSI_EXPRESSION << expression
|
||||||
<< " (" << function_name << ")] " << ANSI_RESET
|
<< ANSI_RESET << " = " << ANSI_VALUE << value_buffer.rdbuf()
|
||||||
<< ANSI_EXPRESSION << expression << ANSI_RESET
|
<< ANSI_RESET << " (" << ANSI_TYPE << type << ANSI_RESET << ")"
|
||||||
<< " = "
|
|
||||||
<< ANSI_VALUE << value_buffer.rdbuf() << ANSI_RESET
|
|
||||||
<< " (" << ANSI_TYPE << type << ANSI_RESET << ")"
|
|
||||||
<< '\n';
|
<< '\n';
|
||||||
|
|
||||||
return std::forward<T>(value);
|
return std::forward<T>(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <unsigned int N>
|
template <unsigned int N>
|
||||||
auto dbg_print(const char (&msg)[N],
|
auto dbg_print(const char (&msg)[N], static_string const &, char const *file,
|
||||||
static_string const&,
|
int line, char const *function_name, char const *expression)
|
||||||
char const* file,
|
-> decltype(msg) {
|
||||||
int line,
|
std::cerr << ANSI_DEBUG << "[" << file << ":" << line << " (" << function_name
|
||||||
char const* function_name,
|
<< ")] " << ANSI_RESET << ANSI_MESSAGE << msg << ANSI_RESET << '\n';
|
||||||
char const* expression) -> decltype(msg) {
|
|
||||||
std::cerr << ANSI_DEBUG
|
|
||||||
<< "[" << file << ":" << line
|
|
||||||
<< " (" << function_name << ")] " << ANSI_RESET
|
|
||||||
<< ANSI_MESSAGE << msg << ANSI_RESET
|
|
||||||
<< '\n';
|
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T> T &&identity(T &&t) { return std::forward<T>(t); }
|
||||||
T&& identity(T&& t) {
|
|
||||||
return std::forward<T>(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // end namespace detail
|
} // end namespace detail
|
||||||
|
|
||||||
} // end namespace dbg_macro
|
} // namespace soi
|
||||||
|
|
||||||
#ifdef SOI_RELEASE
|
#ifdef SOI_RELEASE
|
||||||
#define dbg(...) dbg_macro::identity(__VA_ARGS__)
|
#define dbg(...) dbg_macro::identity(__VA_ARGS__)
|
||||||
#else
|
#else
|
||||||
#define dbg(...) \
|
#define dbg(...) \
|
||||||
soi::detail::dbg_print((__VA_ARGS__), \
|
soi::detail::dbg_print( \
|
||||||
soi::detail::sanitized_type_name<decltype(__VA_ARGS__)>(), \
|
(__VA_ARGS__), \
|
||||||
__FILE__, \
|
soi::detail::sanitized_type_name<decltype(__VA_ARGS__)>(), __FILE__, \
|
||||||
__LINE__, \
|
__LINE__, __func__, #__VA_ARGS__)
|
||||||
__func__, \
|
|
||||||
#__VA_ARGS__)
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // SOI_DBG
|
#endif // SOI_DBG
|
||||||
|
|
|
@ -1,24 +1,32 @@
|
||||||
#pragma GCC diagnostic error "-Wdeprecated-declarations"
|
#pragma GCC diagnostic error "-Wdeprecated-declarations"
|
||||||
|
|
||||||
struct endl_is_evil_t {} endl_is_evil;
|
struct endl_is_evil_t {
|
||||||
[[deprecated("endl is evil. Use '\\n' to print a newline.")]] std::ostream & operator<<(std::ostream &os, endl_is_evil_t);
|
} endl_is_evil;
|
||||||
|
[[deprecated("endl is evil. Use '\\n' to print a newline.")]] std::ostream &
|
||||||
|
operator<<(std::ostream &os, endl_is_evil_t);
|
||||||
#define endl endl_is_evil
|
#define endl endl_is_evil
|
||||||
|
|
||||||
#define printf printf_is_evil
|
#define printf printf_is_evil
|
||||||
#define fprintf fprintf_is_evil
|
#define fprintf fprintf_is_evil
|
||||||
#define sprintf sprintf_is_evil
|
#define sprintf sprintf_is_evil
|
||||||
#define snprintf snprintf_is_evil
|
#define snprintf snprintf_is_evil
|
||||||
[[deprecated("printf is evil. Use cout.")]] int printf(const char *format, ...);
|
[[deprecated("printf is evil. Use cout.")]] int printf(const char *format,
|
||||||
[[deprecated("printf is evil. Use cout.")]] int fprintf(std::FILE *stream, const char *format, ...);
|
...);
|
||||||
[[deprecated("printf is evil. Use cout.")]] int sprintf(char *buffer, const char *format, ...);
|
[[deprecated("printf is evil. Use cout.")]] int
|
||||||
[[deprecated("printf is evil. Use cout.")]] int snprintf(char *buffer, std::size_t buf_size, const char *format, ...);
|
fprintf(std::FILE *stream, const char *format, ...);
|
||||||
|
[[deprecated("printf is evil. Use cout.")]] int
|
||||||
|
sprintf(char *buffer, const char *format, ...);
|
||||||
|
[[deprecated("printf is evil. Use cout.")]] int
|
||||||
|
snprintf(char *buffer, std::size_t buf_size, const char *format, ...);
|
||||||
|
|
||||||
#define scanf scanf_is_evil
|
#define scanf scanf_is_evil
|
||||||
#define fscanf fscanf_is_evil
|
#define fscanf fscanf_is_evil
|
||||||
#define sscanf sscanf_is_evil
|
#define sscanf sscanf_is_evil
|
||||||
[[deprecated("scanf is evil. Use cin.")]] int scanf(const char *format, ...);
|
[[deprecated("scanf is evil. Use cin.")]] int scanf(const char *format, ...);
|
||||||
[[deprecated("scanf is evil. Use cin.")]] int fscanf(std::FILE *stream, const char *format, ...);
|
[[deprecated("scanf is evil. Use cin.")]] int fscanf(std::FILE *stream,
|
||||||
[[deprecated("scanf is evil. Use cin.")]] int sscanf(const char *buffer, const char *format, ...);
|
const char *format, ...);
|
||||||
|
[[deprecated("scanf is evil. Use cin.")]] int sscanf(const char *buffer,
|
||||||
|
const char *format, ...);
|
||||||
|
|
||||||
#define puts puts_is_evil
|
#define puts puts_is_evil
|
||||||
#define fputs fputs_is_evil
|
#define fputs fputs_is_evil
|
||||||
|
@ -35,28 +43,45 @@ struct endl_is_evil_t {} endl_is_evil;
|
||||||
#define fread fread_is_evil
|
#define fread fread_is_evil
|
||||||
#define fwrite fwrite_is_evil
|
#define fwrite fwrite_is_evil
|
||||||
[[deprecated("<cstdio> is evil. Use cin/cout.")]] int puts(const char *str);
|
[[deprecated("<cstdio> is evil. Use cin/cout.")]] int puts(const char *str);
|
||||||
[[deprecated("<cstdio> is evil. Use cin/cout.")]] int fputs(const char *str, FILE *stream);
|
[[deprecated("<cstdio> is evil. Use cin/cout.")]] int fputs(const char *str,
|
||||||
[[deprecated("<cstdio> is evil. Use cin/cout.")]] char *fgets(char *str, int count, FILE *stream);
|
FILE *stream);
|
||||||
[[deprecated("<cstdio> is evil. Use cin/cout.")]] std::FILE *freopen(const char *filename, const char *mode, std::FILE *stream);
|
[[deprecated("<cstdio> is evil. Use cin/cout.")]] char *
|
||||||
[[deprecated("<cstdio> is evil. Use cin/cout.")]] std::FILE *fopen(const char *filename, const char *mode);
|
fgets(char *str, int count, FILE *stream);
|
||||||
[[deprecated("<cstdio> is evil. Use cin/cout.")]] int fclose(std::FILE *stream);
|
[[deprecated("<cstdio> is evil. Use cin/cout.")]] std::FILE *
|
||||||
[[deprecated("<cstdio> is evil. Use cin/cout.")]] int fflush(std::FILE *stream);
|
freopen(const char *filename, const char *mode, std::FILE *stream);
|
||||||
|
[[deprecated("<cstdio> is evil. Use cin/cout.")]] std::FILE *
|
||||||
|
fopen(const char *filename, const char *mode);
|
||||||
|
[[deprecated("<cstdio> is evil. Use cin/cout.")]] int
|
||||||
|
fclose(std::FILE *stream);
|
||||||
|
[[deprecated("<cstdio> is evil. Use cin/cout.")]] int
|
||||||
|
fflush(std::FILE *stream);
|
||||||
[[deprecated("<cstdio> is evil. Use cin/cout.")]] int getchar();
|
[[deprecated("<cstdio> is evil. Use cin/cout.")]] int getchar();
|
||||||
[[deprecated("<cstdio> is evil. Use cin/cout.")]] int fgetc(std::FILE *stream);
|
[[deprecated("<cstdio> is evil. Use cin/cout.")]] int fgetc(std::FILE *stream);
|
||||||
[[deprecated("<cstdio> is evil. Use cin/cout.")]] int getc(std::FILE *stream);
|
[[deprecated("<cstdio> is evil. Use cin/cout.")]] int getc(std::FILE *stream);
|
||||||
[[deprecated("<cstdio> is evil. Use cin/cout.")]] void setbuf(std::FILE *stream, char *buffer);
|
[[deprecated("<cstdio> is evil. Use cin/cout.")]] void
|
||||||
[[deprecated("<cstdio> is evil. Use cin/cout.")]] int setvbuf(std::FILE *stream, char *buffer, int mode, std::size_t size);
|
setbuf(std::FILE *stream, char *buffer);
|
||||||
[[deprecated("<cstdio> is evil. Use cin/cout.")]] std::size_t fread(void *buffer, std::size_t size, std::size_t count, std::FILE *stream);
|
[[deprecated("<cstdio> is evil. Use cin/cout.")]] int
|
||||||
[[deprecated("<cstdio> is evil. Use cin/cout.")]] std::size_t fwrite(const void *buffer, std::size_t size, std::size_t count, std::FILE *stream);
|
setvbuf(std::FILE *stream, char *buffer, int mode, std::size_t size);
|
||||||
|
[[deprecated("<cstdio> is evil. Use cin/cout.")]] std::size_t
|
||||||
|
fread(void *buffer, std::size_t size, std::size_t count, std::FILE *stream);
|
||||||
|
[[deprecated("<cstdio> is evil. Use cin/cout.")]] std::size_t
|
||||||
|
fwrite(const void *buffer, std::size_t size, std::size_t count,
|
||||||
|
std::FILE *stream);
|
||||||
|
|
||||||
#define malloc malloc_is_evil
|
#define malloc malloc_is_evil
|
||||||
#define calloc calloc_is_evil
|
#define calloc calloc_is_evil
|
||||||
#define realloc realloc_is_evil
|
#define realloc realloc_is_evil
|
||||||
#define free free_is_evil
|
#define free free_is_evil
|
||||||
[[deprecated("malloc/free is evil. Use a vector.")]] void *malloc(std::size_t size);
|
[[deprecated("malloc/free is evil. Use a vector.")]] void *
|
||||||
[[deprecated("malloc/free is evil. Use a vector.")]] void *calloc(std::size_t num, std::size_t size);
|
malloc(std::size_t size);
|
||||||
[[deprecated("malloc/free is evil. Use a vector.")]] void *realloc(void *ptr, std::size_t new_size);
|
[[deprecated("malloc/free is evil. Use a vector.")]] void *
|
||||||
[[deprecated("malloc/free is evil. Use a vector.")]] void *free(void *ptr, std::size_t new_size);
|
calloc(std::size_t num, std::size_t size);
|
||||||
|
[[deprecated("malloc/free is evil. Use a vector.")]] void *
|
||||||
|
realloc(void *ptr, std::size_t new_size);
|
||||||
|
[[deprecated("malloc/free is evil. Use a vector.")]] void *
|
||||||
|
free(void *ptr, std::size_t new_size);
|
||||||
|
|
||||||
[[deprecated("new is evil. Use a vector.")]] void *operator new(std::size_t sz);
|
[[deprecated("new is evil. Use a vector.")]] void *
|
||||||
[[deprecated("delete is evil. Use a vector.")]] void operator delete(void *ptr) noexcept;
|
operator new(std::size_t sz);
|
||||||
|
[[deprecated("delete is evil. Use a vector.")]] void
|
||||||
|
operator delete(void *ptr) noexcept;
|
||||||
|
|
|
@ -23,26 +23,52 @@ namespace detail {
|
||||||
template <typename TChar, typename TCharTraits>
|
template <typename TChar, typename TCharTraits>
|
||||||
void escape_char(std::basic_ostream<TChar, TCharTraits> &stream, char c) {
|
void escape_char(std::basic_ostream<TChar, TCharTraits> &stream, char c) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case '\a': stream << "\\a"; break;
|
case '\a':
|
||||||
case '\b': stream << "\\b"; break;
|
stream << "\\a";
|
||||||
case '\t': stream << "\\t"; break;
|
break;
|
||||||
case '\n': stream << "\\n"; break;
|
case '\b':
|
||||||
case '\v': stream << "\\v"; break;
|
stream << "\\b";
|
||||||
case '\f': stream << "\\f"; break;
|
break;
|
||||||
case '\r': stream << "\\r"; break;
|
case '\t':
|
||||||
case '\e': stream << "\\e"; break;
|
stream << "\\t";
|
||||||
case '\"': stream << "\\\""; break;
|
break;
|
||||||
case '\'': stream << "\\'"; break;
|
case '\n':
|
||||||
case '\?': stream << "\\?"; break;
|
stream << "\\n";
|
||||||
case '\\': stream << "\\\\"; break;
|
break;
|
||||||
default: stream << c;
|
case '\v':
|
||||||
}
|
stream << "\\v";
|
||||||
|
break;
|
||||||
|
case '\f':
|
||||||
|
stream << "\\f";
|
||||||
|
break;
|
||||||
|
case '\r':
|
||||||
|
stream << "\\r";
|
||||||
|
break;
|
||||||
|
case '\e':
|
||||||
|
stream << "\\e";
|
||||||
|
break;
|
||||||
|
case '\"':
|
||||||
|
stream << "\\\"";
|
||||||
|
break;
|
||||||
|
case '\'':
|
||||||
|
stream << "\\'";
|
||||||
|
break;
|
||||||
|
case '\?':
|
||||||
|
stream << "\\?";
|
||||||
|
break;
|
||||||
|
case '\\':
|
||||||
|
stream << "\\\\";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
stream << c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
template <typename TChar, typename TCharTraits>
|
template <typename TChar, typename TCharTraits>
|
||||||
std::basic_ostream<TChar, TCharTraits> &
|
std::basic_ostream<TChar, TCharTraits> &
|
||||||
pretty_print(std::basic_ostream<TChar, TCharTraits> & stream, const std::string& x) {
|
pretty_print(std::basic_ostream<TChar, TCharTraits> &stream,
|
||||||
|
const std::string &x) {
|
||||||
stream << "\"";
|
stream << "\"";
|
||||||
for (char c : x)
|
for (char c : x)
|
||||||
detail::escape_char(stream, c);
|
detail::escape_char(stream, c);
|
||||||
|
@ -64,12 +90,11 @@ pretty_print(std::basic_ostream<TChar, TCharTraits> & stream, const T& x) {
|
||||||
return stream << x;
|
return stream << x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template <typename T, typename TChar, typename TCharTraits>
|
template <typename T, typename TChar, typename TCharTraits>
|
||||||
std::basic_ostream<TChar, TCharTraits> &
|
std::basic_ostream<TChar, TCharTraits> &
|
||||||
print(std::basic_ostream<TChar, TCharTraits> &stream, const T &x) {
|
print(std::basic_ostream<TChar, TCharTraits> &stream, const T &x) {
|
||||||
return pretty_print(stream, x);
|
return pretty_print(stream, x);
|
||||||
}
|
}
|
||||||
}
|
} // namespace soi
|
||||||
|
|
||||||
#endif // SOI_PRETTY
|
#endif // SOI_PRETTY
|
||||||
|
|
|
@ -5,8 +5,8 @@
|
||||||
have to understand every concept all at once.
|
have to understand every concept all at once.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <fstream>
|
|
||||||
#include "bits/soi-dbg.hpp"
|
#include "bits/soi-dbg.hpp"
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
namespace soi {
|
namespace soi {
|
||||||
|
|
||||||
|
@ -48,9 +48,9 @@ void initialize_debug() {
|
||||||
std::cin.exceptions(std::ifstream::failbit | std::ifstream::badbit);
|
std::cin.exceptions(std::ifstream::failbit | std::ifstream::badbit);
|
||||||
std::ios::sync_with_stdio(false);
|
std::ios::sync_with_stdio(false);
|
||||||
|
|
||||||
if (should_check_for_eof() &&
|
if (should_check_for_eof() && std::atexit(noninteractive_check_eof) != 0) {
|
||||||
std::atexit(noninteractive_check_eof) != 0) {
|
std::cerr
|
||||||
std::cerr << "WARNING: soi.h -- registration of sanity check at exit failed\n";
|
<< "WARNING: soi.h -- registration of sanity check at exit failed\n";
|
||||||
}
|
}
|
||||||
soi::detail::dbg_init();
|
soi::detail::dbg_init();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue