Classes | Functions
C++ STL customizations

Classes

struct  util::details::ToStringImpl< T, typename >
 
struct  util::details::ToStringImpl< T, std::enable_if_t< util::is_basic_string_type_v< T > > >
 
struct  util::details::ToStringImpl< T, std::enable_if_t< util::is_basic_string_view_type_v< T > > >
 

Functions

template<typename U >
static std::string util::details::ToStringImpl< T, typename >::to_string (U &&obj)
 
template<typename U >
static std::string util::details::ToStringImpl< T, std::enable_if_t< util::is_basic_string_type_v< T > > >::to_string (U &&obj)
 
template<typename U >
static std::string util::details::ToStringImpl< T, std::enable_if_t< util::is_basic_string_view_type_v< T > > >::to_string (U &&obj)
 

C++ standard library customization for user-defined classes.

template<typename T >
decltype(auto) constexpr util::to_string (T &&obj)
 ADL-aware version of std::to_string. More...
 
template<typename T >
decltype(auto) constexpr util::begin (T &&obj)
 ADL-aware version of std::begin. More...
 
template<typename T >
decltype(auto) constexpr util::end (T &&obj)
 ADL-aware version of std::end. More...
 
template<typename T >
decltype(auto) constexpr util::cbegin (T &&obj)
 ADL-aware version of std::cbegin. More...
 
template<typename T >
decltype(auto) constexpr util::cend (T &&obj)
 ADL-aware version of std::cend. More...
 
template<typename T >
decltype(auto) constexpr util::size (T &&obj)
 ADL-aware version of std::size. More...
 
template<typename T >
decltype(auto) constexpr util::empty (T &&obj)
 ADL-aware version of std::empty. More...
 
template<std::size_t I, typename T >
decltype(auto) util::get (T &&obj)
 

Detailed Description

There are a number of functions that are provided by C++ standard library for the data types and classes defined in the standard. It is often desirable to have your class react to these standard functions in a standard way, for example for a container to react to std::begin() to return its begin() iterator. While sometimes this is easy (for example std::begin() calls begin() member function if available), some other times that is not possible. In that case, since overloading of functions in the std namespace is not allowed by C++, the usual pattern is to rely on the argument-dependent lookup (known as "ADL") to have the comnpiler find the overloaded function that is defined in the same namespace as any of the arguments. For example:

userns::MyObj obj;
// ...
std::string objstr = to_string(obj);

will look in the namespace where the type of obj is defined (that is userns) for a userns::to_string, then will consider std::to_string it self.

The utilities provided here provide a transparent way to do that, at the cost of a new header and some non-standard call. The equivalent call of the above would be:

userns::MyObj obj;
// ...
Note
For customization of templates, like std::hash or std::numeric_limits, specialization of classes in std is allowed by the standard, so no particular trick is required.

Function Documentation

template<typename T >
decltype(auto) constexpr util::begin ( T &&  obj)

ADL-aware version of std::begin.

Definition at line 72 of file StdUtils.h.

73  { using std::begin; return begin(std::forward<T>(obj)); }
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
Definition: StdUtils.h:72
template<typename T >
decltype(auto) constexpr util::cbegin ( T &&  obj)

ADL-aware version of std::cbegin.

Definition at line 82 of file StdUtils.h.

83  { using std::cbegin; return cbegin(std::forward<T>(obj)); }
decltype(auto) constexpr cbegin(T &&obj)
ADL-aware version of std::cbegin.
Definition: StdUtils.h:82
template<typename T >
decltype(auto) constexpr util::cend ( T &&  obj)

ADL-aware version of std::cend.

Definition at line 87 of file StdUtils.h.

88  { using std::cend; return cend(std::forward<T>(obj)); }
decltype(auto) constexpr cend(T &&obj)
ADL-aware version of std::cend.
Definition: StdUtils.h:87
template<typename T >
decltype(auto) constexpr util::empty ( T &&  obj)

ADL-aware version of std::empty.

Definition at line 97 of file StdUtils.h.

98  { using std::empty; return empty(std::forward<T>(obj)); }
decltype(auto) constexpr empty(T &&obj)
ADL-aware version of std::empty.
Definition: StdUtils.h:97
template<typename T >
decltype(auto) constexpr util::end ( T &&  obj)

ADL-aware version of std::end.

Definition at line 77 of file StdUtils.h.

78  { using std::end; return end(std::forward<T>(obj)); }
decltype(auto) constexpr end(T &&obj)
ADL-aware version of std::end.
Definition: StdUtils.h:77
template<std::size_t I, typename T >
decltype(auto) util::get ( T &&  obj)

Definition at line 107 of file StdUtils.h.

108  { using std::get; return get<I>(std::forward<T>(obj)); }
decltype(auto) get(T &&obj)
Definition: StdUtils.h:107
template<typename T >
decltype(auto) constexpr util::size ( T &&  obj)

ADL-aware version of std::size.

Definition at line 92 of file StdUtils.h.

93  { using std::size; return size(std::forward<T>(obj)); }
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
Definition: StdUtils.h:92
template<typename T >
decltype(auto) constexpr util::to_string ( T &&  obj)

ADL-aware version of std::to_string.

template<typename T , typename = void>
template<typename U >
static std::string util::details::ToStringImpl< T, typename >::to_string ( U &&  obj)
inlinestatic

Definition at line 127 of file StdUtils.h.

128  { using std::to_string; return to_string(std::forward<U>(obj)); }
decltype(auto) constexpr to_string(T &&obj)
ADL-aware version of std::to_string.
static std::string to_string(U &&obj)
Definition: StdUtils.h:127
template<typename T >
template<typename U >
static std::string util::details::ToStringImpl< T, std::enable_if_t< util::is_basic_string_type_v< T > > >::to_string ( U &&  obj)
inlinestatic

Definition at line 138 of file StdUtils.h.

138 { return obj; }
template<typename T >
template<typename U >
static std::string util::details::ToStringImpl< T, std::enable_if_t< util::is_basic_string_view_type_v< T > > >::to_string ( U &&  obj)
inlinestatic

Definition at line 149 of file StdUtils.h.

149 { return { obj.begin(), obj.end() }; }