1 /* 2 * Copyright (c) Meta Platforms, Inc. and affiliates. 3 * All rights reserved. 4 * 5 * This source code is licensed under the BSD-style license found in the 6 * LICENSE file in the root directory of this source tree. 7 */ 8 9 #pragma once 10 // @lint-ignore-every CLANGTIDY facebook-hte-LocalUncheckedArrayBounds 11 12 #include <ostream> 13 #include <sstream> 14 #include <string> 15 16 namespace vkcompute { 17 namespace utils { 18 19 namespace detail { 20 21 struct CompileTimeEmptyString { 22 operator const std::string&() const { 23 static const std::string empty_string_literal; 24 return empty_string_literal; 25 } 26 operator const char*() const { 27 return ""; 28 } 29 }; 30 31 template <typename T> 32 struct CanonicalizeStrTypes { 33 using type = const T&; 34 }; 35 36 template <size_t N> 37 struct CanonicalizeStrTypes<char[N]> { 38 using type = const char*; 39 }; 40 41 inline std::ostream& _str(std::ostream& ss) { 42 return ss; 43 } 44 45 template <typename T> 46 inline std::ostream& _str(std::ostream& ss, const T& t) { 47 ss << t; 48 return ss; 49 } 50 51 template <> 52 inline std::ostream& _str<CompileTimeEmptyString>( 53 std::ostream& ss, 54 const CompileTimeEmptyString&) { 55 return ss; 56 } 57 58 template <typename T, typename... Args> 59 inline std::ostream& _str(std::ostream& ss, const T& t, const Args&... args) { 60 return _str(_str(ss, t), args...); 61 } 62 63 template <typename... Args> 64 struct _str_wrapper final { 65 static std::string call(const Args&... args) { 66 std::ostringstream ss; 67 _str(ss, args...); 68 return ss.str(); 69 } 70 }; 71 72 template <> 73 struct _str_wrapper<> final { 74 static CompileTimeEmptyString call() { 75 return CompileTimeEmptyString(); 76 } 77 }; 78 79 } // namespace detail 80 81 template <typename... Args> 82 inline std::string concat_str(const Args&... args) { 83 return detail::_str_wrapper< 84 typename detail::CanonicalizeStrTypes<Args>::type...>::call(args...); 85 } 86 87 } // namespace utils 88 } // namespace vkcompute 89