16namespace kassert::internal {
 
   18template <
typename, 
typename, 
typename = 
void>
 
   22template <
typename StreamT, 
typename ValueT>
 
   26    std::
void_t<decltype(std::declval<StreamT&>() << std::declval<ValueT>())>> : std::true_type {};
 
 
   32template <typename StreamT, typename ValueT>
 
   33constexpr bool is_streamable_type = is_streamable_type_impl<StreamT, ValueT>::value;
 
   46template <typename StreamT>
 
   51    explicit Logger(StreamT&& out) : _out_buffer(), _out(std::forward<StreamT>(out)) {
 
   52        _out_buffer << std::boolalpha;
 
 
   58    template <typename ValueT, std::enable_if_t<internal::is_streamable_type<std::ostream, ValueT>, int> = 0>
 
   59    Logger<StreamT>& operator<<(ValueT&& value) {
 
   62        _out_buffer << std::forward<ValueT>(value);
 
   71        return std::forward<StreamT>(_out);
 
 
   76        _out << _out_buffer.str() << std::flush;
 
   77        _out_buffer.str(std::string{});
 
 
   87    std::stringstream _out_buffer; 
 
 
   92namespace kassert::internal {
 
  102template <typename StreamT, typename ValueT>
 
  103void stringify_value(Logger<StreamT>& out, ValueT const& value) {
 
  104    if constexpr (is_streamable_type<Logger<StreamT>, ValueT>) {
 
  113using OStreamLogger = Logger<std::ostream&>;
 
  117using RrefOStringstreamLogger = Logger<std::ostringstream&&>;
 
  135template <typename StreamT, typename ValueT, typename AllocatorT>
 
  136Logger<StreamT>& operator<<(Logger<StreamT>& logger, std::vector<ValueT, AllocatorT> const& container) {
 
  139    for (auto const& element: container) {
 
  146    return logger << "]";
 
 
  160template <typename StreamT, typename Key, typename Value>
 
  161Logger<StreamT>& operator<<(Logger<StreamT>& logger, std::pair<Key, Value> const& pair) {
 
  162    return logger << "(" << pair.first << ", " << pair.second << ")";
 
The left hand size of a decomposed expression. This can either be turned into a BinaryExpr if an oper...
Definition expression_decomposition.hpp:185