Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-17 08:57:47

0001 /***********************************************************************************\
0002 * (c) Copyright 1998-2025 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::tuple in a python like format. E.g. "(1, 2)".
0042   template <typename... Args>
0043   std::ostream& operator<<( std::ostream& s, const std::tuple<Args...>& tuple );
0044 
0045   /// Serialize an std::vector in a python like format. E.g. "[1, 2, 3]".
0046   template <class T, class ALLOC>
0047   std::ostream& operator<<( std::ostream& s, const std::vector<T, ALLOC>& v );
0048 
0049   /// Serialize an std::array in a python like format. E.g. "[1, 2, 3]".
0050   template <class T, std::size_t N>
0051   std::ostream& operator<<( std::ostream& s, const std::array<T, N>& v );
0052 
0053   /// Serialize an std::list in a python like format. E.g. "[1, 2, 3]".
0054   template <class T, class ALLOC>
0055   std::ostream& operator<<( std::ostream& s, const std::list<T, ALLOC>& l );
0056 
0057   /// Serialize an std::set in a python like format. E.g. "[1, 2, 3]".
0058   template <class T, class ALLOC>
0059   std::ostream& operator<<( std::ostream& s, const std::set<T, ALLOC>& l );
0060 
0061   /// Serialize an std::unordered_set in a python like format. E.g. "{1, 2, 3}".
0062   template <class T, class ALLOC>
0063   std::ostream& operator<<( std::ostream& s, const std::unordered_set<T, ALLOC>& l );
0064 
0065   /// Serialize an std::map in a python like format. E.g. "{a: 1, b: 2}".
0066   template <class T1, class T2, class COMP, class ALLOC>
0067   std::ostream& operator<<( std::ostream& s, const std::map<T1, T2, COMP, ALLOC>& m );
0068 
0069   /// Serialize a GaudiUtils::Map in a python like format. E.g. "{a: 1, b: 2}".
0070   template <class K, class T, class M>
0071   std::ostream& operator<<( std::ostream& s, const GaudiUtils::Map<K, T, M>& m );
0072 
0073   /// Serialize a GaudiUtils::HashMap in a python like format. E.g. "{a: 1, b: 2}".
0074   template <class K, class T, class H, class M>
0075   std::ostream& operator<<( std::ostream& s, const GaudiUtils::HashMap<K, T, H, M>& m );
0076 
0077   namespace details {
0078 
0079     struct IdentityOutputter {
0080       template <typename T>
0081       std::ostream& operator()( std::ostream& os, T&& t ) const {
0082         return os << std::forward<T>( t );
0083       }
0084     };
0085 
0086     template <typename Stream, typename Iterator, typename Separator, typename OutputElement = IdentityOutputter>
0087     Stream& ostream_joiner( Stream& os, Iterator first, Iterator last, Separator sep,
0088                             OutputElement output = OutputElement{} ) {
0089       if ( first != last ) output( os, *first++ );
0090       while ( first != last ) output( os << sep, *first++ );
0091       return os;
0092     }
0093 
0094     template <typename Stream, typename Container, typename Separator, typename OutputElement = IdentityOutputter>
0095     Stream& ostream_joiner( Stream& os, const Container& c, Separator sep, OutputElement output = OutputElement{} ) {
0096       using std::begin, std::end;
0097       return ostream_joiner( os, begin( c ), end( c ), sep, output );
0098     }
0099   } // namespace details
0100 
0101   template <class T1, class T2>
0102   std::ostream& operator<<( std::ostream& s, const std::pair<T1, T2>& p ) {
0103     return s << '(' << p.first << ", " << p.second << ')';
0104   }
0105 
0106   template <typename... Args>
0107   std::ostream& operator<<( std::ostream& s, const std::tuple<Args...>& tup ) {
0108     return std::apply(
0109         [&s]( const auto&... a ) -> decltype( auto ) {
0110           unsigned n = sizeof...( a );
0111           if ( n == 1 ) n = 2; // special case in python...
0112           s << " (";
0113           ( ( s << " " << a << ( --n == 0 ? "" : "," ) ), ... );
0114           return s << " )";
0115         },
0116         tup );
0117   }
0118 
0119   template <class T, class ALLOC>
0120   std::ostream& operator<<( std::ostream& s, const std::vector<T, ALLOC>& v ) {
0121     return details::ostream_joiner( s << '[', v, ", " ) << ']';
0122   }
0123 
0124   template <class T, std::size_t N>
0125   std::ostream& operator<<( std::ostream& s, const std::array<T, N>& v ) {
0126     return details::ostream_joiner( s << '[', v, ", " ) << ']';
0127   }
0128 
0129   template <class T, class ALLOC>
0130   std::ostream& operator<<( std::ostream& s, const std::list<T, ALLOC>& l ) {
0131     return details::ostream_joiner( s << '[', l, ", " ) << ']';
0132   }
0133 
0134   template <class T, class ALLOC>
0135   std::ostream& operator<<( std::ostream& s, const std::set<T, ALLOC>& l ) {
0136     return details::ostream_joiner( s << '[', l, ", " ) << ']';
0137   }
0138 
0139   template <class T, class ALLOC>
0140   std::ostream& operator<<( std::ostream& s, const std::unordered_set<T, ALLOC>& l ) {
0141     auto ordered = std::set( l.begin(), l.end() ); // ensure reproducible printout
0142     s << ordered;
0143     return s;
0144   }
0145 
0146   template <class T1, class T2, class COMP, class ALLOC>
0147   std::ostream& operator<<( std::ostream& s, const std::map<T1, T2, COMP, ALLOC>& m ) {
0148     return details::ostream_joiner( s << "{", m, ", ",
0149                                     []( std::ostream& os, const std::pair<const T1, T2>& p ) -> std::ostream& {
0150                                       return os << p.first << ": " << p.second;
0151                                     } )
0152            << "}";
0153   }
0154 
0155   template <class K, class T, class M>
0156   std::ostream& operator<<( std::ostream& s, const GaudiUtils::Map<K, T, M>& m ) {
0157     // Serialize the internal map.
0158     return s << static_cast<const M&>( m );
0159   }
0160 
0161   /// This implementation is not efficient, but very simple. Anyway a print-out
0162   /// of a hash map is not something that we do every second.
0163   template <class K, class T, class H, class M>
0164   std::ostream& operator<<( std::ostream& s, const GaudiUtils::HashMap<K, T, H, M>& m ) {
0165     // Copy the hash map into a map to have it ordered by key.
0166     return s << GaudiUtils::Map<K, T>( m.begin(), m.end() );
0167   }
0168 
0169 } // namespace GaudiUtils
0170 
0171 #endif /*GAUDIKERNEL_SERIALIZESTL_H_*/