1 // RUN: %check_clang_tidy %s boost-use-to-string %t 2 3 namespace std { 4 5 template <typename T> 6 class basic_string {}; 7 8 using string = basic_string<char>; 9 using wstring = basic_string<wchar_t>; 10 } 11 12 namespace boost { 13 template <typename T, typename V> lexical_cast(const V &)14T lexical_cast(const V &) { 15 return T(); 16 }; 17 } 18 19 struct my_weird_type {}; 20 fun(const std::string &)21std::string fun(const std::string &) {} 22 test_to_string1()23void test_to_string1() { 24 25 auto xa = boost::lexical_cast<std::string>(5); 26 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use std::to_string instead of boost::lexical_cast<std::string> [boost-use-to-string] 27 // CHECK-FIXES: auto xa = std::to_string(5); 28 29 auto z = boost::lexical_cast<std::string>(42LL); 30 // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use std::to_string 31 // CHECK-FIXES: auto z = std::to_string(42LL); 32 33 // this should not trigger 34 fun(boost::lexical_cast<std::string>(42.0)); 35 auto non = boost::lexical_cast<my_weird_type>(42); 36 boost::lexical_cast<int>("12"); 37 } 38 test_to_string2()39void test_to_string2() { 40 int a; 41 long b; 42 long long c; 43 unsigned d; 44 unsigned long e; 45 unsigned long long f; 46 float g; 47 double h; 48 long double i; 49 bool j; 50 51 fun(boost::lexical_cast<std::string>(a)); 52 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use std::to_string 53 // CHECK-FIXES: fun(std::to_string(a)); 54 fun(boost::lexical_cast<std::string>(b)); 55 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use std::to_string 56 // CHECK-FIXES: fun(std::to_string(b)); 57 fun(boost::lexical_cast<std::string>(c)); 58 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use std::to_string 59 // CHECK-FIXES: fun(std::to_string(c)); 60 fun(boost::lexical_cast<std::string>(d)); 61 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use std::to_string 62 // CHECK-FIXES: fun(std::to_string(d)); 63 fun(boost::lexical_cast<std::string>(e)); 64 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use std::to_string 65 // CHECK-FIXES: fun(std::to_string(e)); 66 fun(boost::lexical_cast<std::string>(f)); 67 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use std::to_string 68 // CHECK-FIXES: fun(std::to_string(f)); 69 70 // No change for floating numbers. 71 fun(boost::lexical_cast<std::string>(g)); 72 fun(boost::lexical_cast<std::string>(h)); 73 fun(boost::lexical_cast<std::string>(i)); 74 // And bool. 75 fun(boost::lexical_cast<std::string>(j)); 76 } 77 fun(const std::wstring &)78std::string fun(const std::wstring &) {} 79 test_to_wstring()80void test_to_wstring() { 81 int a; 82 long b; 83 long long c; 84 unsigned d; 85 unsigned long e; 86 unsigned long long f; 87 float g; 88 double h; 89 long double i; 90 bool j; 91 92 fun(boost::lexical_cast<std::wstring>(a)); 93 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use std::to_wstring instead of boost::lexical_cast<std::wstring> [boost-use-to-string] 94 // CHECK-FIXES: fun(std::to_wstring(a)); 95 fun(boost::lexical_cast<std::wstring>(b)); 96 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use std::to_wstring 97 // CHECK-FIXES: fun(std::to_wstring(b)); 98 fun(boost::lexical_cast<std::wstring>(c)); 99 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use std::to_wstring 100 // CHECK-FIXES: fun(std::to_wstring(c)); 101 fun(boost::lexical_cast<std::wstring>(d)); 102 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use std::to_wstring 103 // CHECK-FIXES: fun(std::to_wstring(d)); 104 fun(boost::lexical_cast<std::wstring>(e)); 105 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use std::to_wstring 106 // CHECK-FIXES: fun(std::to_wstring(e)); 107 fun(boost::lexical_cast<std::wstring>(f)); 108 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use std::to_wstring 109 // CHECK-FIXES: fun(std::to_wstring(f)); 110 111 // No change for floating numbers 112 fun(boost::lexical_cast<std::wstring>(g)); 113 fun(boost::lexical_cast<std::wstring>(h)); 114 fun(boost::lexical_cast<std::wstring>(i)); 115 // and bool. 116 fun(boost::lexical_cast<std::wstring>(j)); 117 } 118 119 const auto glob = boost::lexical_cast<std::string>(42); 120 // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: use std::to_string 121 // CHECK-FIXES: const auto glob = std::to_string(42); 122 123 template <typename T> string_as_T(T t=T ())124void string_as_T(T t = T()) { 125 boost::lexical_cast<std::string>(42); 126 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use std::to_string 127 // CHECK-FIXES: std::to_string(42); 128 129 boost::lexical_cast<T>(42); 130 string_as_T(boost::lexical_cast<T>(42)); 131 auto p = boost::lexical_cast<T>(42); 132 auto p2 = (T)boost::lexical_cast<T>(42); 133 auto p3 = static_cast<T>(boost::lexical_cast<T>(42)); 134 } 135 136 #define my_to_string boost::lexical_cast<std::string> 137 no_fixup_inside_macro()138void no_fixup_inside_macro() { 139 my_to_string(12); 140 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use std::to_string 141 } 142 no_warnings()143void no_warnings() { 144 fun(boost::lexical_cast<std::string>("abc")); 145 fun(boost::lexical_cast<std::wstring>("abc")); 146 fun(boost::lexical_cast<std::string>(my_weird_type{})); 147 string_as_T<int>(); 148 string_as_T<std::string>(); 149 } 150 151 struct Fields { 152 int integer; 153 float floating; 154 Fields* wierd; getConstIntegerFields155 const int &getConstInteger() const {return integer;} 156 }; 157 testFields()158void testFields() { 159 Fields fields; 160 auto s1 = boost::lexical_cast<std::string>(fields.integer); 161 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use std::to_string 162 // CHECK-FIXES: auto s1 = std::to_string(fields.integer); 163 164 auto s2 = boost::lexical_cast<std::string>(fields.floating); 165 auto s3 = boost::lexical_cast<std::string>(fields.wierd); 166 auto s4 = boost::lexical_cast<std::string>(fields.getConstInteger()); 167 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use std::to_string 168 // CHECK-FIXES: auto s4 = std::to_string(fields.getConstInteger()); 169 } 170