Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:57:44

0001 /***********************************************************************************\
0002 * (c) Copyright 1998-2023 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 // ============================================================================
0012 #ifndef GAUDIPROPERTYPARSERS_PARSERVALUETOSTREAM_H
0013 #define GAUDIPROPERTYPARSERS_PARSERVALUETOSTREAM_H 1
0014 // ============================================================================
0015 // Include files
0016 // ============================================================================
0017 // STD & STL
0018 // ============================================================================
0019 #include <array>
0020 #include <iomanip>
0021 #include <iostream>
0022 #include <list>
0023 #include <map>
0024 #include <set>
0025 #include <sstream>
0026 #include <string>
0027 #include <type_traits>
0028 #include <unordered_set>
0029 #include <vector>
0030 // ============================================================================
0031 // GaudiKernel
0032 // ============================================================================
0033 #include "GaudiKernel/HashMap.h"
0034 #include "GaudiKernel/Map.h"
0035 #include "GaudiKernel/SerializeSTL.h"
0036 #include "GaudiKernel/VectorMap.h"
0037 // ============================================================================
0038 /** @file GaudiKernel/ToStream.h
0039  *  implementation of various functions for streaming.
0040  *  this functionality is essential for usage of various types as property for
0041  *  the various Gaudi components
0042  *  @attention the implementation of the specific specializations must be done
0043  *                    before the inclusion of this file
0044  *  @todo ToStream.h : reimplement in terms of functors, to allow
0045  *                     easier specializations
0046  */
0047 // ============================================================================
0048 namespace Gaudi {
0049   // ==========================================================================
0050   namespace Utils {
0051     // ========================================================================
0052     /** the generic implementation of the printout to the std::ostream
0053      *  @author Alexander MAZUROV Alexander.Mazurov@gmail.com
0054      *  @author Vanya BELYAEV ibelyaev@physics.syr.edu
0055      *  @date 2006-05-12
0056      */
0057     template <class TYPE>
0058     std::ostream& toStream( const TYPE& obj, std::ostream& s );
0059     // ========================================================================
0060     /** the helper function to print the sequence
0061      *  @param first (INPUT)  begin-iterator for the sequence
0062      *  @param last  (INPUT)  end-iterator for the sequence
0063      *  @param s     (UPDATE) the stream itself
0064      *  @param open  (INPUT)  "open"-symbol
0065      *  @param close (INPUT)  "close"-symbol
0066      *  @param delim (INPUT)  "delimiter"-symbol
0067      *  @return the stream
0068      *  @author Vanya BELYAEV Ivan.BElyaev@nikhef.nl
0069      *  @date 2009-09-15
0070      */
0071     template <class ITERATOR>
0072     inline std::ostream& toStream( ITERATOR           first,   // begin of the sequence
0073                                    ITERATOR           last,    //   end of the sequence
0074                                    std::ostream&      s,       //            the stream
0075                                    const std::string& open,    //               opening
0076                                    const std::string& close,   //               closing
0077                                    const std::string& delim ); //             delimiter
0078     // ========================================================================
0079     /** the printtout of the strings.
0080      *  the string is printed a'la Python using the quotes
0081      *  @author Alexander MAZUROV Alexander.Mazurov@gmail.com
0082      *  @author Vanya BELYAEV ibelyaev@physics.syr.edu
0083      *  @date 2006-05-12
0084      */
0085     inline std::ostream& toStream( const std::string& obj, std::ostream& s ) { return s << std::quoted( obj, '\'' ); }
0086     /** the printout of boolean values "a'la Python"
0087      *  @author Vanya BELYAEV ibelyaev@physics.syr.edu
0088      *  @date 2006-09-09
0089      */
0090     inline std::ostream& toStream( const bool obj, std::ostream& s ) { return s << ( obj ? "True" : "False" ); }
0091     /** the printout of float values with the reasonable precision
0092      *  @author Vanya BELYAEV ibelyaev@physics.syr.edu
0093      *  @date 2006-09-09
0094      */
0095     inline std::ostream& toStream( const float obj, std::ostream& s, const int prec = 6 ) {
0096       const int p = static_cast<int>( s.precision() );
0097       return s << std::setprecision( prec ) << obj << std::setprecision( p );
0098     }
0099     /** the printout of double values with the reasonable precision
0100      *  @author Vanya BELYAEV ibelyaev@physics.syr.edu
0101      *  @date 2006-09-09
0102      */
0103     inline std::ostream& toStream( const double obj, std::ostream& s, const int prec = 8 ) {
0104       const int p = static_cast<int>( s.precision() );
0105       return s << std::setprecision( prec ) << obj << std::setprecision( p );
0106     }
0107     /** the printout of long double values with the reasonable precision
0108      *  @author Vanya BELYAEV ibelyaev@physics.syr.edu
0109      *  @date 2006-09-09
0110      */
0111     inline std::ostream& toStream( const long double obj, std::ostream& s, const int prec = 10 ) {
0112       const int p = static_cast<int>( s.precision() );
0113       return s << std::setprecision( prec ) << obj << std::setprecision( p );
0114     }
0115     // ========================================================================
0116     /** the partial template specialization of
0117      *  <c>std::pair<KTYPE,VTYPE></c> printout
0118      *  the pair is printed a'la Python tuple: " ( a , b )"
0119      *  @author Alexander MAZUROV Alexander.Mazurov@gmail.com
0120      *  @author Vanya BELYAEV ibelyaev@physics.syr.edu
0121      *  @date 2006-05-12
0122      */
0123     template <class KTYPE, class VTYPE>
0124     inline std::ostream& toStream( const std::pair<KTYPE, VTYPE>& obj, std::ostream& s ) {
0125       return toStream( obj.second, toStream( obj.first, s << "( " ) << " , " ) << " )";
0126     }
0127     // ========================================================================
0128     /** the partial template specialization of <c>std::vector<TYPE,ALLOCATOR></c>
0129      *  printout. The vector is printed a'la Python list: "[ a, b, c ]"
0130      *  @author Alexander MAZUROV Alexander.Mazurov@gmail.com
0131      *  @author Vanya BELYAEV ibelyaev@physics.syr.edu
0132      *  @date 2006-05-12
0133      */
0134     template <class TYPE, class ALLOCATOR>
0135     inline std::ostream& toStream( const std::vector<TYPE, ALLOCATOR>& obj, std::ostream& s ) {
0136       return toStream( obj.begin(), obj.end(), s, "[ ", " ]", " , " );
0137     }
0138     // ========================================================================
0139     /** the partial template specialization of <c>std::list<TYPE,ALLOCATOR></c>
0140      *  printout. The vector is printed a'la Python list: "[ a, b, c ]"
0141      *  @author Alexander MAZUROV Alexander.Mazurov@gmail.com
0142      *  @author Vanya BELYAEV ibelyaev@physics.syr.edu
0143      *  @date 2007-04-08
0144      */
0145     template <class TYPE, class ALLOCATOR>
0146     inline std::ostream& toStream( const std::list<TYPE, ALLOCATOR>& obj, std::ostream& s ) {
0147       return toStream( obj.begin(), obj.end(), s, "[ ", " ]", " , " );
0148     }
0149     // ========================================================================
0150     /** the partial template specialization of <c>std::set<TYPE,CMP,ALLOCATOR></c>
0151      *  printout. The vector is printed a'la Python list: "[ a, b, c ]"
0152      *  @author Alexander MAZUROV Alexander.Mazurov@gmail.com
0153      *  @author Vanya BELYAEV ibelyaev@physics.syr.edu
0154      *  @date 2006-05-12
0155      */
0156     template <class TYPE, class CMP, class ALLOCATOR>
0157     inline std::ostream& toStream( const std::set<TYPE, CMP, ALLOCATOR>& obj, std::ostream& s ) {
0158       return toStream( obj.begin(), obj.end(), s, "[ ", " ]", " , " );
0159     }
0160     // ========================================================================
0161     /** the partial template specialization of <c>std::unordered_set<TYPE,HASH,CMP,ALLOCATOR></c>
0162      *  printout. The set is printed a'la Python set: "{ a, b, c }"
0163      */
0164     template <class TYPE, class HASH, class CMP, class ALLOCATOR>
0165     inline std::ostream& toStream( const std::unordered_set<TYPE, HASH, CMP, ALLOCATOR>& obj, std::ostream& s ) {
0166       auto ordered = std::set( obj.begin(), obj.end() ); // ensure reproducible printout
0167       return obj.empty() ? s << "set()" : toStream( ordered.begin(), ordered.end(), s, "{ ", " }", " , " );
0168     }
0169     // ========================================================================
0170     /** the partial template specialization of
0171      *  <c>std::map<KTYPE,VTYPE,CMP,ALLOCATOR></c> printout
0172      *  the map is printed a'la Python dict: " ( a : b , c: d , e : f )"
0173      *  @author Alexander MAZUROV Alexander.Mazurov@gmail.com
0174      *  @author Vanya BELYAEV ibelyaev@physics.syr.edu
0175      *  @date 2006-05-12
0176      */
0177     template <class KTYPE, class VTYPE, class CMP, class ALLOCATOR>
0178     inline std::ostream& toStream( const std::map<KTYPE, VTYPE, CMP, ALLOCATOR>& obj, std::ostream& s ) {
0179       using GaudiUtils::details::ostream_joiner;
0180       return ostream_joiner( s << "{ ", obj, " , ",
0181                              []( std::ostream& os, const std::pair<const KTYPE, VTYPE>& i ) -> std::ostream& {
0182                                return toStream( i.second, toStream( i.first, os ) << " : " );
0183                              } )
0184              << " }";
0185     }
0186     // ========================================================================
0187     /** the partial template specialization of
0188      *  <c>GaudiUtils::VectorMap<KTYPE,VTYPE,CMP,ALLOCATOR></c> printout
0189      *  the map is printed a'la Python dict: " ( a : b , c: d , e : f )"
0190      *  @see GaudiUtils::VectorMap
0191      *  @author Alexander MAZUROV Alexander.Mazurov@gmail.com
0192      *  @author Vanya BELYAEV ibelyaev@physics.syr.edu
0193      *  @date 2006-05-12
0194      */
0195     template <class KTYPE, class VTYPE, class CMP, class ALLOCATOR>
0196     inline std::ostream& toStream( const GaudiUtils::VectorMap<KTYPE, VTYPE, CMP, ALLOCATOR>& obj, std::ostream& s ) {
0197       using GaudiUtils::details::ostream_joiner;
0198       return ostream_joiner( s << "{ ", obj, " , ",
0199                              []( std::ostream& os, const std::pair<const KTYPE, VTYPE>& i ) -> std::ostream& {
0200                                return toStream( i.second, toStream( i.first, os ) << " : " );
0201                              } )
0202              << " }";
0203     }
0204     // ========================================================================
0205     /** the partial template specialization of
0206      *  <c>GaudiUtils::Map<KTYPE,VTYPE,MAP></c> printout
0207      *  the map is printed a'la Python dict: " ( a : b , c: d , e : f )"
0208      *  @see GaudiUtils::VectorMap
0209      *  @author Alexander MAZUROV Alexander.Mazurov@gmail.com
0210      *  @author Vanya BELYAEV ibelyaev@physics.syr.edu
0211      *  @date 2006-05-12
0212      */
0213     template <class KTYPE, class VTYPE, class MAP>
0214     inline std::ostream& toStream( const GaudiUtils::Map<KTYPE, VTYPE, MAP>& obj, std::ostream& s ) {
0215       using GaudiUtils::details::ostream_joiner;
0216       return ostream_joiner( s << "{ ", obj, " , ",
0217                              []( std::ostream& os, const std::pair<const KTYPE, VTYPE>& i ) -> std::ostream& {
0218                                return toStream( i.second, toStream( i.first, os ) << " : " );
0219                              } )
0220              << " }";
0221     }
0222     // ========================================================================
0223     /** the partial template specialization of
0224      *  <c>GaudiUtils::HashMap<KTYPE,VTYPE,HASH,MAP></c> printout
0225      *  the map is printed a'la Python dict: " ( a : b , c: d , e : f )"
0226      *  @see GaudiUtils::VectorMap
0227      *  @author Alexander MAZUROV Alexander.Mazurov@gmail.com
0228      *  @author Vanya BELYAEV ibelyaev@physics.syr.edu
0229      *  @date 2006-05-12
0230      */
0231     template <class KTYPE, class VTYPE, class HASH, class MAP>
0232     inline std::ostream& toStream( const GaudiUtils::HashMap<KTYPE, VTYPE, HASH, MAP>& obj, std::ostream& s ) {
0233       // Copy the hash map into a map to have it ordered by key.
0234       return toStream( GaudiUtils::Map<KTYPE, VTYPE>{ obj.begin(), obj.end() }, s );
0235     }
0236     // ========================================================================
0237     /** the specialization for C-arrays, a'la python tuple
0238      *  @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
0239      *  @date 2009-10-05
0240      */
0241     template <class TYPE, unsigned int N>
0242     std::ostream& toStream( const TYPE ( &obj )[N], std::ostream& s ) {
0243       if constexpr ( N == 1 ) {
0244         return toStream( obj[0], s << "( " ) << " , )";
0245       } else {
0246         return toStream( obj, obj + N, s, "( ", " )", " , " );
0247       }
0248     }
0249     // ========================================================================
0250     /** the specialization for std::array, a'la python tuple
0251      *  @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
0252      *  @date 2009-09-16
0253      */
0254     template <class TYPE, std::size_t N>
0255     std::ostream& toStream( const std::array<TYPE, N>& obj, std::ostream& s ) {
0256       if constexpr ( N == 1 ) {
0257         return toStream( obj[0], s << "( " ) << " , )";
0258       } else {
0259         return toStream( begin( obj ), end( obj ), s, "( ", " )", " , " );
0260       }
0261     }
0262     // ========================================================================
0263     /** the specialization for C-string, a'la python tuple
0264      *  @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
0265      *  @date 2009-10-05
0266      */
0267     template <unsigned int N>
0268     std::ostream& toStream( const char ( &obj )[N], std::ostream& s ) {
0269       return toStream( std::string( obj, obj + N ), s );
0270     }
0271     // ========================================================================
0272     /** the specialization for C-string, a'la python tuple
0273      *  @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
0274      *  @date 2009-10-05
0275      */
0276     inline std::ostream& toStream( const char* obj, std::ostream& s ) { return toStream( std::string( obj ), s ); }
0277     // ========================================================================
0278     /** the generic implementation of the printout to the std::ostream
0279      *  @author Alexander MAZUROV Alexander.Mazurov@gmail.com
0280      *  @author Vanya BELYAEV ibelyaev@physics.syr.edu
0281      *  @date 2006-05-12
0282      */
0283     template <class TYPE>
0284     inline std::ostream& toStream( const TYPE& obj, std::ostream& s ) {
0285       return s << obj;
0286     }
0287     // ========================================================================
0288     /** the helper function to print the sequence
0289      *  @param first (INPUT)  begin-iterator for the sequence
0290      *  @param last  (INPUT)  end-iterator for the sequence
0291      *  @param s     (UPDATE) the stream itself
0292      *  @param open  (INPUT)  "open"-symbol
0293      *  @param close (INPUT)  "close"-symbol
0294      *  @param delim (INPUT)  "delimiter"-symbol
0295      *  @return the stream
0296      *  @author Vanya BELYAEV Ivan.BElyaev@nikhef.nl
0297      *  @date 2009-09-15
0298      */
0299     template <class ITERATOR>
0300     inline std::ostream& toStream( ITERATOR           first,  // begin of the sequence
0301                                    ITERATOR           last,   //   end of the sequence
0302                                    std::ostream&      s,      //            the stream
0303                                    const std::string& open,   //               opening
0304                                    const std::string& close,  //               closing
0305                                    const std::string& delim ) //             delimiter
0306     {
0307       using ref_t = typename std::iterator_traits<ITERATOR>::reference;
0308       using GaudiUtils::details::ostream_joiner;
0309       return ostream_joiner( s << open, first, last, delim,
0310                              []( std::ostream& os, ref_t i ) -> std::ostream& { return toStream( i, os ); } )
0311              << close;
0312     }
0313     // ========================================================================
0314     // helper function to print a tuple of any size
0315     template <class Tuple, std::size_t N>
0316     struct TuplePrinter {
0317       static std::ostream& toStream( const Tuple& t, std::ostream& s ) {
0318         TuplePrinter<Tuple, N - 1>::toStream( t, s ) << " , ";
0319         return Gaudi::Utils::toStream( std::get<N - 1>( t ), s );
0320       }
0321     };
0322 
0323     template <class Tuple>
0324     struct TuplePrinter<Tuple, 1> {
0325       static std::ostream& toStream( const Tuple& t, std::ostream& s ) {
0326         return Gaudi::Utils::toStream( std::get<0>( t ), s );
0327       }
0328     };
0329 
0330     /** the helper function to print the tuple
0331      *  @param tuple (INPUT)  tuple
0332      *  @return the stream
0333      *  @author Aleander Mazurov alexander.mazurov@cern.ch
0334      *  @date 2015-03-21
0335      */
0336     template <typename... Args>
0337     inline std::ostream& toStream( const std::tuple<Args...>& tuple, std::ostream& s ) {
0338       auto& out = TuplePrinter<decltype( tuple ), sizeof...( Args )>::toStream( tuple, s << " ( " );
0339       if constexpr ( std::tuple_size_v<std::tuple<Args...>> == 1 ) { // this is a special case in Python
0340         out << " ,";
0341       }
0342       return out << " ) ";
0343     }
0344 
0345     // ========================================================================
0346     /** the generic implementation of the type conversion to the string
0347      *  @author Alexander MAZUROV Alexander.Mazurov@gmail.com
0348      *  @author Vanya BELYAEV ibelyaev@physics.syr.edu
0349      *  @date 2006-05-12
0350      *  @see Gaudi::Utils::toStream
0351      *  @todo need to be compared with boost::lexical_cast
0352      */
0353     template <class TYPE>
0354     inline std::string toString( const TYPE& obj ) {
0355       std::ostringstream s;
0356       std::ios::fmtflags orig_flags = s.flags();
0357       s.setf( std::ios::showpoint ); // to display correctly floats
0358       toStream( obj, s );
0359       s.flags( orig_flags );
0360       return s.str();
0361     }
0362     // ========================================================================
0363   } // namespace Utils
0364   // ==========================================================================
0365 } //                                                     end of namespace Gaudi
0366 // ============================================================================
0367 // The END
0368 // ============================================================================
0369 #endif