You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							125 lines
						
					
					
						
							3.8 KiB
						
					
					
				
			
		
		
	
	
							125 lines
						
					
					
						
							3.8 KiB
						
					
					
				| //  Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved.
 | |
| //
 | |
| // Licensed under the Apache License, Version 2.0 (the "License");
 | |
| // you may not use this file except in compliance with the License.
 | |
| // You may obtain a copy of the License at
 | |
| //
 | |
| //    http://www.apache.org/licenses/LICENSE-2.0
 | |
| //
 | |
| // Unless required by applicable law or agreed to in writing, software
 | |
| // distributed under the License is distributed on an "AS IS" BASIS,
 | |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | |
| // See the License for the specific language governing permissions and
 | |
| // limitations under the License.
 | |
| 
 | |
| // Compared with std::stringstream, there are primary purpose of
 | |
| // string::Printf:
 | |
| //
 | |
| // 1. Type-safe printing, with why and how explained in
 | |
| //    http://www.drdobbs.com/stringprintf-a-typesafe-printf-family-fo/184401999.
 | |
| //    Implementation includes
 | |
| //
 | |
| //    https://github.com/c42f/tinyformat
 | |
| //    boost::format
 | |
| //    std::stringstream
 | |
| //
 | |
| //    std::stringstream is not convenient enough in many cases.  For example:
 | |
| //
 | |
| //      std::cout << std::setprecision(2) << std::fixed << 1.23456 << "\n";
 | |
| //
 | |
| //    boost::format is the most convenient one.  We can have
 | |
| //
 | |
| //      std::cout << format("%2% %1%") % 36 % 77;
 | |
| //
 | |
| //    or
 | |
| //
 | |
| //      format fmter("%2% %1%");
 | |
| //      fmter % 36; fmter % 77;
 | |
| //      std::cout << fmter.c_str();
 | |
| //
 | |
| //    But the overloading of % might be overkilling and it would be
 | |
| //    more efficient if it can write to std::cout directly.
 | |
| //
 | |
| //    tinyformat has an interface compatible with the C-printf style,
 | |
| //    and it can writes to a stream or returns a std::string:
 | |
| //
 | |
| //      std::cout << tfm::printf(
 | |
| //                  "%s, %s %d, %.2d:%.2d\n",
 | |
| //                  weekday, month, day, hour, min);
 | |
| //
 | |
| //    or
 | |
| //
 | |
| //      tfm::format(std::cout,
 | |
| //                  "%s, %s %d, %.2d:%.2d\n",
 | |
| //                  weekday, month, day, hour, min);
 | |
| //
 | |
| // 2. High-performance -- most printed strings are not too long and
 | |
| //    doens't need dynamic memory allocation.  Many StringPrintf
 | |
| //    implementations doesn't enforce type-safe, but are
 | |
| //    high-performance, including
 | |
| //
 | |
| //    https://developers.google.com/optimization/reference/base/stringprintf/
 | |
| //    https://github.com/adobe/chromium/blob/master/base/stringprintf.h
 | |
| //    https://github.com/google/protobuf/blob/master/src/google/protobuf/stubs/stringprintf.h
 | |
| //
 | |
| // According to
 | |
| // https://github.com/c42f/tinyformat#compile-time-and-code-bloat,
 | |
| // boost::format runs too slow and results in large executable binary
 | |
| // files.  So here we port tinyformat.
 | |
| 
 | |
| #pragma once
 | |
| 
 | |
| #include <iostream>
 | |
| #include <sstream>
 | |
| #include <string>
 | |
| #include <vector>
 | |
| 
 | |
| #include "tinyformat/tinyformat.h"  // https://github.com/c42f/tinyformat
 | |
| 
 | |
| namespace paddle {
 | |
| namespace string {
 | |
| 
 | |
| template <typename... Args>
 | |
| void Fprintf(std::ostream& out, const char* fmt, const Args&... args) {
 | |
|   tinyformat::vformat(out, fmt, tinyformat::makeFormatList(args...));
 | |
| }
 | |
| 
 | |
| inline std::string Sprintf() { return ""; }
 | |
| 
 | |
| template <typename... Args>
 | |
| std::string Sprintf(const Args&... args) {
 | |
|   std::ostringstream oss;
 | |
|   Fprintf(oss, "%s", args...);
 | |
|   return oss.str();
 | |
| }
 | |
| 
 | |
| template <typename... Args>
 | |
| std::string Sprintf(const char* fmt, const Args&... args) {
 | |
|   std::ostringstream oss;
 | |
|   Fprintf(oss, fmt, args...);
 | |
|   return oss.str();
 | |
| }
 | |
| 
 | |
| template <typename... Args>
 | |
| void Printf(const char* fmt, const Args&... args) {
 | |
|   Fprintf(std::cout, fmt, args...);
 | |
| }
 | |
| 
 | |
| inline std::string HumanReadableSize(double f_size) {
 | |
|   size_t i = 0;
 | |
|   double orig = f_size;
 | |
|   const std::vector<std::string> units(
 | |
|       {"B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"});
 | |
|   while (f_size >= 1024) {
 | |
|     f_size /= 1024;
 | |
|     i++;
 | |
|   }
 | |
|   if (i >= units.size()) {
 | |
|     return Sprintf("%fB", orig);
 | |
|   }
 | |
|   return Sprintf("%f%s", f_size, units[i]);
 | |
| }
 | |
| 
 | |
| }  // namespace string
 | |
| }  // namespace paddle
 |