|
||||
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
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |