Changeset 685
- Timestamp:
- 05/03/08 12:06:52 (8 months ago)
- Files:
-
- trunk/phobos/std/string.d (modified) (18 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/phobos/std/string.d
r675 r685 32 32 //debug=string; // uncomment to turn on debugging printf's 33 33 34 private import std.algorithm; 34 35 private import std.stdio; 35 36 private import std.c.stdio; … … 37 38 private import std.c.string; 38 39 private import std.utf; 40 private import std.encoding; 39 41 private import std.uni; 40 42 private import std.array; … … 91 93 92 94 /********************************* 93 * Convert string to integer. 94 */ 95 96 long atoi(in string s) 97 { 98 return std.c.stdlib.atoi(toStringz(s)); 95 Convert string $(D s) to integer. $(RED Scheduled for deprecation. Use 96 the $(D to!(int)(s)) or $(D parse!(int)(s)) routines in $(WEB 97 std_conv, std.conv)). 98 */ 99 100 long atoi(C)(in C[] s) 101 { 102 return to!(long)(s);//std.c.stdlib.atoi(toStringz(s)); 99 103 } 100 104 101 105 /************************************* 102 * Convert string to real. 103 */ 104 105 real atof(in string s) 106 { char* endptr; 107 108 auto result = strtold(toStringz(s), &endptr); 109 return result; 106 Convert string to real. $(RED Scheduled for deprecation. Use the $(D 107 to!(int)(s)) or $(D parse!(int)(s)) routines in $(WEB std_conv, 108 std.conv)). 109 */ 110 111 real atof(C)(in C[] s) 112 { 113 return parse!(real)(s); 114 } 115 116 unittest 117 { 118 alias TypeTuple!(char, wchar, dchar, 119 const char, const wchar, const dchar, 120 invariant char, invariant wchar, invariant dchar) 121 AllChars; 122 foreach (Char; AllChars) 123 { 124 auto s = to!(Char[])("123"); 125 assert(atoi(s) == 123); 126 } 110 127 } 111 128 … … 120 137 */ 121 138 122 int cmp(in char[] s1, in char[] s2) 123 { 124 auto len = s1.length; 125 int result; 126 127 //printf("cmp('%.*s', '%.*s')\n", s1, s2); 128 if (s2.length < len) 129 len = s2.length; 130 result = memcmp(s1.ptr, s2.ptr, len); 131 if (result == 0) 132 result = cast(int)s1.length - cast(int)s2.length; 133 return result; 139 int cmp(C1, C2)(in C1[] s1, in C2[] s2) 140 { 141 static if (C1.sizeof == C2.sizeof) 142 { 143 invariant len = min(s1.length, s2.length); 144 invariant result = std.c.string.memcmp(s1.ptr, s2.ptr, len); 145 return result ? result : cast(int)s1.length - cast(int)s2.length; 146 } 147 else 148 { 149 size_t i1, i2; 150 for (;;) 151 { 152 if (i1 == s1.length) return s2.length - i2; 153 if (i2 == s2.length) return s1.length - i1; 154 invariant c1 = std.utf.decode(s1, i1), 155 c2 = std.utf.decode(s2, i2); 156 if (c1 != c2) return cast(int) c1 - cast(int) c2; 157 } 158 } 134 159 } 135 160 … … 140 165 int icmp(in char[] s1, in char[] s2) 141 166 { 142 auto len = s1.length; 143 int result; 144 145 if (s2.length < len) 146 len = s2.length; 147 version (Win32) 148 { 149 result = memicmp(s1.ptr, s2.ptr, len); 150 } 151 version (linux) 152 { 153 for (size_t i = 0; i < len; i++) 154 { 155 if (s1[i] != s2[i]) 156 { 157 char c1 = s1[i]; 158 char c2 = s2[i]; 159 160 if (c1 >= 'A' && c1 <= 'Z') 161 c1 += cast(int)'a' - cast(int)'A'; 162 if (c2 >= 'A' && c2 <= 'Z') 163 c2 += cast(int)'a' - cast(int)'A'; 164 result = cast(int)c1 - cast(int)c2; 165 if (result) 166 break; 167 } 168 } 169 } 170 if (result == 0) 171 result = cast(int)s1.length - cast(int)s2.length; 172 return result; 167 size_t i1, i2; 168 for (;;) 169 { 170 if (i1 == s1.length) return i2 - s2.length; 171 if (i2 == s2.length) return s1.length - i1; 172 auto c1 = std.utf.decode(s1, i1), 173 c2 = std.utf.decode(s2, i2); 174 if (c1 >= 'A' && c1 <= 'Z') 175 c1 += cast(int)'a' - cast(int)'A'; 176 if (c2 >= 'A' && c2 <= 'Z') 177 c2 += cast(int)'a' - cast(int)'A'; 178 if (c1 != c2) return cast(int) c1 - cast(int) c2; 179 } 173 180 } 174 181 … … 199 206 */ 200 207 201 deprecated c har* toCharz(instring s)208 deprecated const(char)* toCharz(string s) 202 209 { 203 210 return toStringz(s); … … 209 216 */ 210 217 211 c har* toStringz(const(char)[] s)218 const(char)* toStringz(const(char)[] s) 212 219 in 213 220 { … … 250 257 } 251 258 259 // /// Ditto 260 // const(char)* toStringz(invariant(char)[] s) 261 // { 262 // /* Peek past end of s[], if it's 0, no conversion necessary. 263 // * Note that the compiler will put a 0 past the end of static 264 // * strings, and the storage allocator will put a 0 past the end 265 // * of newly allocated char[]'s. 266 // */ 267 // invariant p = &s[0] + s.length; 268 // if (*p == 0) 269 // return s.ptr; 270 // return toStringz(cast(const char[]) s); 271 // } 272 252 273 unittest 253 274 { 254 275 debug(string) printf("string.toStringz.unittest\n"); 255 276 256 char*p = toStringz("foo");277 auto p = toStringz("foo"); 257 278 assert(strlen(p) == 3); 258 279 const(char) foo[] = "abbzxyzzy"; … … 325 346 int ifind(in char[] s, dchar c) 326 347 { 327 char* p;328 329 348 if (c <= 0x7F) 330 349 { // Plain old ASCII … … 865 884 } 866 885 886 /** 887 Converts $(D s) to lowercase in place. 888 */ 889 890 void tolowerInPlace(C)(ref C[] s) 891 { 892 for (size_t i = 0; i < s.length; ) 893 { 894 invariant c = s[i]; 895 if ('A' <= c && c <= 'Z') 896 { 897 s[i++] = cast(C) (c + (cast(C)'a' - 'A')); 898 } 899 else if (c > 0x7F) 900 { 901 // wide character 902 size_t j = i; 903 dchar dc = decode(s, j); 904 assert(j > i); 905 if (!std.uni.isUniUpper(dc)) 906 { 907 i = j; 908 continue; 909 } 910 auto toAdd = to!(C[])(std.uni.toUniLower(dc)); 911 s = s[0 .. i] ~ toAdd ~ s[j .. $]; 912 i += toAdd.length; 913 } 914 else 915 { 916 ++i; 917 } 918 } 919 } 920 867 921 unittest 868 922 { … … 876 930 assert(s2 != s1); 877 931 932 char[] s3 = s1.dup; 933 tolowerInPlace(s3); 934 assert(s3 == s2, s3); 935 878 936 s1 = "A\u0100B\u0101d"; 879 937 s2 = tolower(s1); 938 s3 = s1.dup; 880 939 assert(cmp(s2, "a\u0101b\u0101d") == 0); 881 940 assert(s2 !is s1); 941 tolowerInPlace(s3); 942 assert(s3 == s2, s3); 882 943 883 944 s1 = "A\u0460B\u0461d"; 884 945 s2 = tolower(s1); 946 s3 = s1.dup; 885 947 assert(cmp(s2, "a\u0461b\u0461d") == 0); 886 948 assert(s2 !is s1); 949 tolowerInPlace(s3); 950 assert(s3 == s2, s3); 887 951 888 952 s1 = "\u0130"; 889 953 s2 = tolower(s1); 954 s3 = s1.dup; 890 955 assert(s2 == "i"); 891 956 assert(s2 !is s1); 957 tolowerInPlace(s3); 958 assert(s3 == s2, s3); 892 959 } 893 960 … … 941 1008 } 942 1009 1010 /** 1011 Converts $(D s) to uppercase in place. 1012 */ 1013 1014 void toupperInPlace(C)(ref C[] s) 1015 { 1016 for (size_t i = 0; i < s.length; ) 1017 { 1018 invariant c = s[i]; 1019 if ('a' <= c && c <= 'z') 1020 { 1021 s[i++] = cast(C) (c - (cast(C)'a' - 'A')); 1022 } 1023 else if (c > 0x7F) 1024 { 1025 // wide character 1026 size_t j = i; 1027 dchar dc = decode(s, j); 1028 assert(j > i); 1029 if (!std.uni.isUniLower(dc)) 1030 { 1031 i = j; 1032 continue; 1033 } 1034 auto toAdd = to!(C[])(std.uni.toUniUpper(dc)); 1035 s = s[0 .. i] ~ toAdd ~ s[j .. $]; 1036 i += toAdd.length; 1037 } 1038 else 1039 { 1040 ++i; 1041 } 1042 } 1043 } 1044 943 1045 unittest 944 1046 { … … 947 1049 string s1 = "FoL"; 948 1050 string s2; 1051 char[] s3; 949 1052 950 1053 s2 = toupper(s1); 1054 s3 = s1.dup; toupperInPlace(s3); 1055 assert(s3 == s2, s3); 951 1056 assert(cmp(s2, "FOL") == 0); 952 1057 assert(s2 !is s1); … … 954 1059 s1 = "a\u0100B\u0101d"; 955 1060 s2 = toupper(s1); 1061 s3 = s1.dup; toupperInPlace(s3); 1062 assert(s3 == s2); 956 1063 assert(cmp(s2, "A\u0100B\u0100D") == 0); 957 1064 assert(s2 !is s1); … … 959 1066 s1 = "a\u0460B\u0461d"; 960 1067 s2 = toupper(s1); 1068 s3 = s1.dup; toupperInPlace(s3); 1069 assert(s3 == s2); 961 1070 assert(cmp(s2, "A\u0460B\u0460D") == 0); 962 1071 assert(s2 !is s1); … … 1140 1249 */ 1141 1250 1142 string join( string[] words, string sep)1251 string join(in string[] words, string sep) 1143 1252 { 1144 1253 char[] result; … … 4335 4444 continue; 4336 4445 if (c == '-' || c == '_' || c == '?' || 4337 c == '=' || c == '%' || c == '&' ||4338 c == '/' || c == '+' || c == '#' ||4339 c == '~')4446 c == '=' || c == '%' || c == '&' || 4447 c == '/' || c == '+' || c == '#' || 4448 c == '~') 4340 4449 continue; 4341 4450 if (c == '.') … … 4356 4465 } 4357 4466 4358 // Undocum mented yet4359 4360 string stringize(T...)(T args)4361 { 4362 stringresult;4467 // Undocumented yet 4468 4469 private S textImpl(S, T...)(T args) 4470 { 4471 S result; 4363 4472 foreach (arg; args) 4364 4473 { 4365 result ~= to!( string)(arg);4474 result ~= to!(S)(arg); 4366 4475 } 4367 4476 return result; 4368 4477 } 4478 4479 string text(T...)(T args) { return textImpl!(string, T)(args); } 4480 wstring wtext(T...)(T args) { return textImpl!(wstring, T)(args); } 4481 dstring dtext(T...)(T args) { return textImpl!(dstring, T)(args); } 4482 4483 unittest 4484 { 4485 assert(text(42, ' ', 1.5, ": xyz") == "42 1.5: xyz"); 4486 assert(wtext(42, ' ', 1.5, ": xyz") == "42 1.5: xyz"w); 4487 assert(dtext(42, ' ', 1.5, ": xyz") == "42 1.5: xyz"d); 4488 }
