Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-11 08:32:12

0001 /***********************************************************************************\
0002 * (c) Copyright 1998-2024 CERN for the benefit of the LHCb and ATLAS collaborations *
0003 *                                                                                   *
0004 * This software is distributed under the terms of the Apache version 2 licence,     *
0005 * copied verbatim in the file "LICENSE".                                            *
0006 *                                                                                   *
0007 * In applying this licence, CERN does not waive the privileges and immunities       *
0008 * granted to it by virtue of its status as an Intergovernmental Organization        *
0009 * or submit itself to any jurisdiction.                                             *
0010 \***********************************************************************************/
0011 /** @file GaudiKernel/SerializeSTL.h
0012  *
0013  * Provide serialization function (output only) for some common STL classes
0014  * (vectors, lists, pairs, maps) plus GaudiUtils::Map and GaudiUtils::HashMap.
0015  *
0016  * To use the serializer provided by this file, one should add
0017  * "using namespace GaudiUtils" (possibly inside the function (scope) calling "<<").
0018  *
0019  * @author Marco Clemencic
0020  * (adapted from the code found in LHCbKernel, original author unknown)
0021  */
0022 #ifndef GAUDIKERNEL_SERIALIZESTL_H_
0023 #define GAUDIKERNEL_SERIALIZESTL_H_
0024 
0025 #include <GaudiKernel/HashMap.h>
0026 #include <GaudiKernel/Map.h>
0027 #include <array>
0028 #include <list>
0029 #include <map>
0030 #include <ostream>
0031 #include <set>
0032 #include <unordered_set>
0033 #include <utility>
0034 #include <vector>
0035 
0036 namespace GaudiUtils {
0037   /// Serialize an std::pair in a python like format. E.g. "(1, 2)".
0038   template <class T1, class T2>
0039   std::ostream& operator<<( std::ostream& s, const std::pair<T1, T2>& p );
0040 
0041   /// Serialize an std::vector in a python like format. E.g. "[1, 2, 3]".
0042   template <class T, class ALLOC>
0043   std::ostream& operator<<( std::ostream& s, const std::vector<T, ALLOC>& v );
0044 
0045   /// Serialize an std::array in a python like format. E.g. "[1, 2, 3]".
0046   template <class T, std::size_t N>
0047   std::ostream& operator<<( std::ostream& s, const std::array<T, N>& v );
0048 
0049   /// Serialize an std::list in a python like format. E.g. "[1, 2, 3]".
0050   template <class T, class ALLOC>
0051   std::ostream& operator<<( std::ostream& s, const std::list<T, ALLOC>& l );
0052 
0053   /// Serialize an std::map in a python like format. E.g. "{a: 1, b: 2}".
0054   template <class T1, class T2, class COMP, class ALLOC>
0055   std::ostream& operator<<( std::ostream& s, const std::map<T1, T2, COMP, ALLOC>& m );
0056 
0057   /// Serialize a GaudiUtils::Map in a python like format. E.g. "{a: 1, b: 2}".
0058   template <class K, class T, class M>
0059   std::ostream& operator<<( std::ostream& s, const GaudiUtils::Map<K, T, M>& m );
0060 
0061   /// Serialize a GaudiUtils::HashMap in a python like format. E.g. "{a: 1, b: 2}".
0062   template <class K, class T, class H, class M>
0063   std::ostream& operator<<( std::ostream& s, const GaudiUtils::HashMap<K, T, H, M>& m );
0064 
0065   namespace details {
0066 
0067     struct IdentityOutputter {
0068       template <typename T>
0069       std::ostream& operator()( std::ostream& os, T&& t ) const {
0070         return os << std::forward<T>( t );
0071       }
0072     };
0073 
0074     template <typename Stream, typename Iterator, typename Separator, typename OutputElement = IdentityOutputter>
0075     Stream& ostream_joiner( Stream& os, Iterator first, Iterator last, Separator sep,
0076                             OutputElement output = OutputElement{} ) {
0077       if ( first != last ) output( os, *first++ );
0078       while ( first != last ) output( os << sep, *first++ );
0079       return os;
0080     }
0081 
0082     template <typename Stream, typename Container, typename Separator, typename OutputElement = IdentityOutputter>
0083     Stream& ostream_joiner( Stream& os, const Container& c, Separator sep, OutputElement output = OutputElement{} ) {
0084       using std::begin, std::end;
0085       return ostream_joiner( os, begin( c ), end( c ), sep, output );
0086     }
0087   } // namespace details
0088 
0089   template <class T1, class T2>
0090   std::ostream& operator<<( std::ostream& s, const std::pair<T1, T2>& p ) {
0091     return s << '(' << p.first << ", " << p.second << ')';
0092   }
0093 
0094   template <class T, class ALLOC>
0095   std::ostream& operator<<( std::ostream& s, const std::vector<T, ALLOC>& v ) {
0096     return details::ostream_joiner( s << '[', v, ", " ) << ']';
0097   }
0098 
0099   template <class T, std::size_t N>
0100   std::ostream& operator<<( std::ostream& s, const std::array<T, N>& v ) {
0101     return details::ostream_joiner( s << '[', v, ", " ) << ']';
0102   }
0103 
0104   template <class T, class ALLOC>
0105   std::ostream& operator<<( std::ostream& s, const std::list<T, ALLOC>& l ) {
0106     return details::ostream_joiner( s << '[', l, ", " ) << ']';
0107   }
0108 
0109   template <class T, class ALLOC>
0110   std::ostream& operator<<( std::ostream& s, const std::set<T, ALLOC>& l ) {
0111     return details::ostream_joiner( s << '[', l, ", " ) << ']';
0112   }
0113 
0114   template <class T, class ALLOC>
0115   std::ostream& operator<<( std::ostream& s, const std::unordered_set<T, ALLOC>& l ) {
0116     auto ordered = std::set( l.begin(), l.end() ); // ensure reproducible printout
0117     s << ordered;
0118     return s;
0119   }
0120 
0121   template <class T1, class T2, class COMP, class ALLOC>
0122   std::ostream& operator<<( std::ostream& s, const std::map<T1, T2, COMP, ALLOC>& m ) {
0123     return details::ostream_joiner( s << "{", m, ", ",
0124                                     []( std::ostream& os, const std::pair<const T1, T2>& p ) -> std::ostream& {
0125                                       return os << p.first << ": " << p.second;
0126                                     } )
0127            << "}";
0128   }
0129 
0130   template <class K, class T, class M>
0131   std::ostream& operator<<( std::ostream& s, const GaudiUtils::Map<K, T, M>& m ) {
0132     // Serialize the internal map.
0133     return s << static_cast<const M&>( m );
0134   }
0135 
0136   /// This implementation is not efficient, but very simple. Anyway a print-out
0137   /// of a hash map is not something that we do every second.
0138   template <class K, class T, class H, class M>
0139   std::ostream& operator<<( std::ostream& s, const GaudiUtils::HashMap<K, T, H, M>& m ) {
0140     // Copy the hash map into a map to have it ordered by key.
0141     return s << GaudiUtils::Map<K, T>( m.begin(), m.end() );
0142   }
0143 
0144 } // namespace GaudiUtils
0145 
0146 #endif /*GAUDIKERNEL_SERIALIZESTL_H_*/