Branch data Line data Source code
1 : : // ***************************************************************************** 2 : : /*! 3 : : \file src/Base/TaggedTupleDeepPrint.hpp 4 : : \copyright 2012-2015 J. Bakosi, 5 : : 2016-2018 Los Alamos National Security, LLC., 6 : : 2019-2021 Triad National Security, LLC. 7 : : All rights reserved. See the LICENSE file for details. 8 : : \brief Structured TaggedTuple printer with depth/indentation 9 : : \details Structured TaggedTuple printer with depth/indentation. 10 : : */ 11 : : // ***************************************************************************** 12 : : #ifndef TaggedTupleDeepPrint_h 13 : : #define TaggedTupleDeepPrint_h 14 : : 15 : : #include <ostream> 16 : : 17 : : #include <brigand/algorithms/for_each.hpp> 18 : : #include <brigand/sequences/has_key.hpp> 19 : : 20 : : #include "NoWarning/format.hpp" 21 : : #include "NoWarning/set.hpp" 22 : : 23 : : #include "Has.hpp" 24 : : 25 : : // The include order here is important: it populates the overloads of 26 : : // operator<< for various types, followed by TaggedTuple, the (simple) 27 : : // TaggedTuplePrint (which will be accessible by the upstream, simpler 28 : : // operator<< for vector, map, etc.) and finally, the most complex TaggedTuple 29 : : // printer with depth, defined below. 30 : : #include "PrintUtil.hpp" 31 : : #include "TaggedTuple.hpp" 32 : : #include "TaggedTuplePrint.hpp" 33 : : 34 : : namespace tk { 35 : : 36 : : //! Function object type to print contents of a TaggedTuple at depth 37 : : //! \details Compared to tk::TuplePrinter this prints every key and value 38 : : //! in a new line and nested tagged tuples starts at increasing depths 39 : : //! (indents). 40 : : //! \tparam List brigand::list of types in the tagged tuple 41 : : //! \tparam Ignore brigand::list of types to not print 42 : : template< class List, class Ignore = brigand::set<> > 43 : : struct DeepTuplePrinter { 44 : : std::ostream& os; 45 : : const tk::TaggedTuple< List >& tuple; 46 : : std::size_t& depth; 47 : : //! Constructor 48 : 960 : DeepTuplePrinter( std::ostream& s, const tk::TaggedTuple< List >& t, 49 : 960 : std::size_t& d ) : os(s), tuple(t), depth(d) {} 50 : : //! Function call operator templated on the type being output 51 : 33984 : template< typename Key > void operator()( brigand::type_<Key> ) { 52 : : using ignored = brigand::has_key< Ignore, Key >; 53 : : if constexpr( std::is_same_v< ignored, brigand::false_type > ) { 54 : : using Tuple = tk::TaggedTuple< List >; 55 : 26688 : const auto& key = Key::name(); 56 [ + - ]: 33984 : const auto& value = tuple.template get< Key >(); 57 : : if constexpr( Tuple::template is_tagged_tuple< Key >::value ) { 58 [ + - ]: 2880 : std::string indent( depth * 2, ' ' ); 59 [ + - ][ + - ]: 5760 : os << '\n' << indent << '\'' << key << "' {"; [ + - ][ + - ] 60 : : using ituple = typename Tuple::template TupleElement< Key >; 61 : : using ikeys = typename ituple::Keys; 62 : : using ilist = typename ituple::PairList; 63 [ - - ]: 3840 : brigand::for_each< ikeys >( 64 [ + - ]: 2880 : DeepTuplePrinter< ilist, Ignore >( os, value, ++depth ) ); 65 [ + - ][ + - ]: 2880 : os << '\n' << indent << '}'; 66 [ - + ]: 2880 : --depth; 67 : : } else { 68 [ + - ]: 31104 : std::string indent( depth * 2, ' ' ); 69 [ + - ][ + - ]: 62208 : os << boost::format("\n%s%-15s : ") % indent % key; [ - - ] 70 [ + - ]: 31104 : os << std::boolalpha << value; 71 : : } 72 : : } 73 : 33984 : } 74 : : }; 75 : : 76 : : //! Output command line object (a TaggedTuple) to file 77 : : //! \tparam Tuple Tuple object type 78 : : //! \param[in,out] os Output stream to print to 79 : : //! \param[in] name Name of (root) Tuple 80 : : //! \param[in] c Command line object to output to file 81 : : template< class Tuple > 82 : 192 : void print( std::ostream& os, const std::string& name, const Tuple& c ) { 83 : : static_assert( tk::HasTypedef_i_am_tagged_tuple_v< Tuple > ); 84 : : using Keys = typename Tuple::Keys; 85 : : using Ignore = typename Tuple::ignore; 86 : : using List = typename Tuple::PairList; 87 : 192 : os << "# vim: filetype=sh:\n#\n" 88 : : "# Contents of a tagged tuple.\n#\n" 89 : : "# A string in single quotes denotes the name/tag of a (nested)\n" 90 : : "# tagged tuple. The contents of tuples are enclosed within braces.\n" 91 : : "# Vectors are enclosed within square brackets. Keys of associative\n" 92 : : "# containers are in paretheses.\n\n"; 93 : 192 : os << '\'' << name << "' {"; 94 : 192 : std::size_t depth = 1; 95 : 192 : brigand::for_each< Keys >( DeepTuplePrinter< List, Ignore >( os, c, depth ) ); 96 : 192 : os << "\n}"; 97 : 192 : } 98 : : 99 : : } // tk:: 100 : : 101 : : #endif // TaggedTupleDeepPrint_h