1 /* Praat_tests.cpp 2 * 3 * Copyright (C) 2001-2007,2009,2011-2020 Paul Boersma 4 * 5 * This code is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or (at 8 * your option) any later version. 9 * 10 * This code is distributed in the hope that it will be useful, but 11 * WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 13 * See the GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this work. If not, see <http://www.gnu.org/licenses/>. 17 */ 18 19 /* December 10, 2006: MelderInfo */ 20 /* November 5, 2007: wchar */ 21 /* 21 March 2009: modern enums */ 22 /* 24 May 2011: C++ */ 23 /* 5 June 2015: char32 */ 24 25 #include "FileInMemoryManager.h" 26 #include "Praat_tests.h" 27 28 #include "Graphics.h" 29 #include "praat.h" 30 #include "NUM2.h" 31 #include "Sound.h" 32 33 #include "enums_getText.h" 34 #include "Praat_tests_enums.h" 35 #include "enums_getValue.h" 36 #include "Praat_tests_enums.h" 37 #include <string> 38 39 static void testAutoData (autoDaata data) { 40 fprintf (stderr, "testAutoData: %p %p\n", data.get(), data -> name.get()); 41 } 42 static void testAutoDataRef (autoDaata& data) { 43 fprintf (stderr, "testAutoDataRef: %p %p\n", data.get(), data -> name.get()); 44 } 45 static void testData (Daata data) { 46 fprintf (stderr, "testData: %p %s\n", data, Melder_peek32to8 (data -> name.get())); 47 } 48 static autoDaata newAutoData () { 49 autoDaata data (Thing_new (Daata)); 50 return data; 51 } 52 static integer length (conststring32 s) { 53 integer result = str32len (s); 54 Melder_free (s); 55 return result; 56 } 57 58 static autoMAT constantHH (integer nrow, integer ncol, double value) { 59 autoMAT result = raw_MAT (nrow, ncol); 60 result.all() <<= value; 61 return result; 62 } 63 64 int Praat_tests (kPraatTests itest, conststring32 arg1, conststring32 arg2, conststring32 arg3, conststring32 arg4) { 65 int64 n = Melder_atoi (arg1); 66 double t = 0.0; 67 (void) arg1; 68 (void) arg2; 69 (void) arg3; 70 (void) arg4; 71 Melder_clearInfo (); 72 Melder_stopwatch (); 73 switch (itest) { 74 case kPraatTests::UNDEFINED: 75 case kPraatTests::_: 76 case kPraatTests::CHECK_RANDOM_1009_2009: { 77 } break; 78 case kPraatTests::TIME_RANDOM_FRACTION: { 79 for (int64 i = 1; i <= n; i ++) 80 (void) NUMrandomFraction (); 81 t = Melder_stopwatch (); 82 } break; 83 case kPraatTests::TIME_RANDOM_GAUSS: { 84 for (int64 i = 1; i <= n; i ++) 85 (void) NUMrandomGauss (0.0, 1.0); 86 t = Melder_stopwatch (); 87 } break; 88 case kPraatTests::TIME_SORT: { 89 integer size = Melder_atoi (arg2); 90 autoVEC array = raw_VEC (size); 91 Melder_stopwatch (); 92 for (int64 iteration = 1; iteration <= n; iteration ++) { 93 for (int64 i = 1; i <= size; i ++) 94 array [i] = NUMrandomFraction (); 95 sort_VEC_inout (array.get()); 96 } 97 t = Melder_stopwatch () / (size * log2 (size)); 98 } break; 99 case kPraatTests::TIME_INTEGER: { 100 int64 sum = 0; 101 for (int64 i = 1; i <= n; i ++) 102 sum += i * (i - 1) * (i - 2); 103 t = Melder_stopwatch (); 104 MelderInfo_writeLine (sum); 105 } break; 106 case kPraatTests::TIME_FLOAT: { 107 double sum = 0.0, fn = n; 108 for (double fi = 1.0; fi <= fn; fi += 1.0) 109 sum += fi * (fi - 1.0) * (fi - 2.0); 110 t = Melder_stopwatch (); // 2.02 ns 111 MelderInfo_writeLine (sum); 112 } break; 113 case kPraatTests::TIME_FLOAT_TO_UNSIGNED_BUILTIN: { 114 uint64 sum = 0; 115 double fn = n; 116 for (double fi = 1.0; fi <= fn; fi += 1.0) 117 sum += (uint32) fi; 118 t = Melder_stopwatch (); // 1.45 ns 119 MelderInfo_writeLine (sum); 120 } break; 121 case kPraatTests::TIME_FLOAT_TO_UNSIGNED_EXTERN: { 122 uint64 sum = 0; 123 double fn = n; 124 for (double fi = 1.0; fi <= fn; fi += 1.0) 125 sum += (uint32) ((int32) (fi - 2147483648.0) + 2147483647L + 1); 126 t = Melder_stopwatch (); // 1.47 ns 127 MelderInfo_writeLine (sum); 128 } break; 129 case kPraatTests::TIME_UNSIGNED_TO_FLOAT_BUILTIN: { 130 double sum = 0.0; 131 uint32 nu = (uint32) n; 132 for (uint32 iu = 1; iu <= nu; iu ++) 133 sum += (double) iu; 134 t = Melder_stopwatch (); // 0.88 ns 135 MelderInfo_writeLine (sum); 136 } break; 137 case kPraatTests::TIME_UNSIGNED_TO_FLOAT_EXTERN: { 138 double sum = 0.0; 139 uint32 nu = (uint32) n; 140 for (uint32 iu = 1; iu <= nu; iu ++) 141 sum += (double) (int32) (iu - 2147483647L - 1) + 2147483648.0; 142 t = Melder_stopwatch (); // 0.87 ns 143 MelderInfo_writeLine (sum); 144 } break; 145 case kPraatTests::TIME_STRING_MELDER_32: { 146 autoMelderString string; 147 char32 word [] { U"abc" }; 148 word [2] = char32 (NUMrandomInteger (U'a', U'z')); 149 for (int64 i = 1; i <= n; i ++) { 150 MelderString_copy (& string, word); 151 for (int j = 1; j <= 30; j ++) 152 MelderString_append (& string, word); 153 } 154 t = Melder_stopwatch (); 155 } break; 156 case kPraatTests::TIME_STRING_MELDER_32_ALLOC: { 157 char32 word [] { U"abc" }; 158 word [2] = char32 (NUMrandomInteger (U'a', U'z')); 159 for (int64 i = 1; i <= n; i ++) { 160 autoMelderString string; 161 MelderString_copy (& string, word); 162 for (int j = 1; j <= 30; j ++) 163 MelderString_append (& string, word); 164 } 165 t = Melder_stopwatch (); 166 } break; 167 case kPraatTests::TIME_STRING_CPP_S: { 168 std::string s = ""; 169 char word [] { "abc" }; 170 word [2] = char (NUMrandomInteger ('a', 'z')); 171 for (int64 i = 1; i <= n; i ++) { 172 s = word; 173 for (int j = 1; j <= 30; j ++) 174 s += word; 175 } 176 t = Melder_stopwatch (); 177 } break; 178 case kPraatTests::TIME_STRING_CPP_C: { 179 std::basic_string<char> s = ""; 180 char word [] { "abc" }; 181 word [2] = char (NUMrandomInteger ('a', 'z')); 182 for (int64 i = 1; i <= n; i ++) { 183 s = word; 184 for (int j = 1; j <= 30; j ++) 185 s += word; 186 } 187 t = Melder_stopwatch (); 188 } break; 189 case kPraatTests::TIME_STRING_CPP_WS: { 190 std::wstring s = L""; 191 wchar_t word [] { L"abc" }; 192 word [2] = wchar_t (NUMrandomInteger (L'a', L'z')); 193 for (int64 i = 1; i <= n; i ++) { 194 s = word; 195 for (int j = 1; j <= 30; j ++) 196 s += word; 197 } 198 t = Melder_stopwatch (); 199 } break; 200 case kPraatTests::TIME_STRING_CPP_WC: { 201 std::basic_string<wchar_t> s = L""; 202 wchar_t word [] { L"abc" }; 203 word [2] = wchar_t (NUMrandomInteger (L'a', L'z')); 204 for (int64 i = 1; i <= n; i ++) { 205 s = word; 206 for (int j = 1; j <= 30; j ++) 207 s += word; 208 } 209 t = Melder_stopwatch (); 210 } break; 211 case kPraatTests::TIME_STRING_CPP_32: { 212 std::basic_string<char32_t> s = U""; 213 char32 word [] { U"abc" }; 214 word [2] = char32 (NUMrandomInteger (U'a', U'z')); 215 for (int64 i = 1; i <= n; i ++) { 216 s = word; 217 for (int j = 1; j <= 30; j ++) 218 s += word; 219 } 220 t = Melder_stopwatch (); 221 } break; 222 case kPraatTests::TIME_STRING_CPP_U32STRING: { 223 std::u32string s = U""; 224 char32 word [] { U"abc" }; 225 word [2] = char32 (NUMrandomInteger (U'a', U'z')); 226 for (int64 i = 1; i <= n; i ++) { 227 s = word; 228 for (int j = 1; j <= 30; j ++) 229 s += word; 230 } 231 t = Melder_stopwatch (); 232 } break; 233 case kPraatTests::TIME_STRCPY: { 234 char buffer [100]; 235 char word [] { "abc" }; 236 word [2] = (char) NUMrandomInteger ('a', 'z'); 237 for (int64 i = 1; i <= n; i ++) { 238 strcpy (buffer, word); 239 for (int j = 1; j <= 30; j ++) 240 strcpy (buffer + strlen (buffer), word); 241 } 242 t = Melder_stopwatch (); 243 MelderInfo_writeLine (Melder_peek8to32 (buffer)); 244 } break; 245 case kPraatTests::TIME_WCSCPY: { 246 wchar_t buffer [100]; 247 wchar_t word [] { L"abc" }; 248 word [2] = wchar_t (NUMrandomInteger (L'a', L'z')); 249 for (int64 i = 1; i <= n; i ++) { 250 wcscpy (buffer, word); 251 for (int j = 1; j <= 30; j ++) 252 wcscpy (buffer + wcslen (buffer), word); 253 } 254 t = Melder_stopwatch (); 255 } break; 256 case kPraatTests::TIME_STR32CPY: { 257 char32 buffer [100]; 258 char32 word [] { U"abc" }; 259 word [2] = char32 (NUMrandomInteger (U'a', U'z')); 260 for (int64 i = 1; i <= n; i ++) { 261 str32cpy (buffer, word); 262 for (int j = 1; j <= 30; j ++) 263 str32cpy (buffer + str32len (buffer), word); 264 } 265 t = Melder_stopwatch (); 266 MelderInfo_writeLine (buffer); 267 } break; 268 case kPraatTests::TIME_GRAPHICS_TEXT_TOP: { 269 autoPraatPicture picture; 270 for (int64 i = 1; i <= n; i ++) { 271 Graphics_textTop (GRAPHICS, false, U"hello world"); 272 } 273 t = Melder_stopwatch (); 274 } break; 275 case kPraatTests::TIME_UNDEFINED_NUMUNDEFINED: { 276 bool isAllDefined = true; 277 double x = 0.0; 278 for (int64 i = 1; i <= n; i ++) { 279 x += (double) i; 280 isAllDefined &= ( x != undefined ); 281 } 282 t = Melder_stopwatch (); // 0.86 ns 283 MelderInfo_writeLine (isAllDefined, U" ", x); 284 } break; 285 case kPraatTests::TIME_UNDEFINED_ISINF_OR_ISNAN: { 286 bool isAllDefined = true; 287 double x = 0.0; 288 for (int64 i = 1; i <= n; i ++) { 289 x += (double) i; 290 isAllDefined &= ! std::isinf (x) && ! std::isnan (x); 291 //isAllDefined &= ! isfinite (x); // same 292 } 293 t = Melder_stopwatch (); // 1.29 ns 294 MelderInfo_writeLine (isAllDefined, U" ", x); 295 } break; 296 case kPraatTests::TIME_UNDEFINED_0x7FF: { 297 bool isAllDefined = true; 298 double x = 0.0; 299 for (int64 i = 1; i <= n; i ++) { 300 x += (double) i; 301 isAllDefined &= ((* (uint64 *) & x) & 0x7FF0'0000'0000'0000) != 0x7FF0'0000'0000'0000; 302 } 303 t = Melder_stopwatch (); // 0.90 ns 304 MelderInfo_writeLine (isAllDefined, U" ", x); 305 } break; 306 case kPraatTests::TIME_INNER: { 307 integer size = Melder_atoi (arg2); 308 autoVEC x = randomGauss_VEC (size, 0.0, 1.0); 309 autoVEC y = randomGauss_VEC (size, 0.0, 1.0); 310 double z = 0.0; 311 for (int64 i = 1; i <= n; i ++) 312 z += NUMinner (x.get(), y.get()); 313 t = Melder_stopwatch () / size; // 2.9 Gops = 5.8 Gflops (multiplication-addition pair) 314 MelderInfo_writeLine (z); 315 } break; 316 case kPraatTests::TIME_OUTER_NUMMAT: { 317 integer nrow = 100, ncol = 100; 318 autoVEC x = randomGauss_VEC (nrow, 0.0, 1.0); 319 autoVEC y = randomGauss_VEC (ncol, 0.0, 1.0); 320 for (int64 i = 1; i <= n; i ++) 321 const autoMAT mat = outer_MAT (x.get(), y.get()); 322 t = Melder_stopwatch () / nrow / ncol; // 6.1 Gops, i.e. less than one clock cycle per cell 323 } break; 324 case kPraatTests::CHECK_INVFISHERQ: { 325 MelderInfo_writeLine (NUMinvFisherQ (0.003, 1, 100000)); 326 } break; 327 case kPraatTests::TIME_AUTOSTRING: { 328 conststring32 strings [6] = { U"ghdg", U"jhd", U"hkfjjd", U"fhfj", U"jhksfd", U"hfjs" }; 329 int64 sumOfLengths = 0; 330 for (int64 i = 1; i <= n; i ++) { 331 int istring = i % 6; 332 autostring32 s = Melder_dup (strings [istring]); 333 sumOfLengths += length (s.transfer()); 334 } 335 t = Melder_stopwatch (); // 72 ns (but 152 bytes more) 336 MelderInfo_writeLine (sumOfLengths); 337 } break; 338 case kPraatTests::TIME_CHAR32: { 339 conststring32 strings [6] = { U"ghdg", U"jhd", U"hkfjjd", U"fhfj", U"jhksfd", U"hfjs" }; 340 int64 sumOfLengths = 0; 341 for (int64 i = 1; i <= n; i ++) { 342 int istring = i % 6; 343 char32 *s = Melder_dup (strings [istring]).transfer(); 344 sumOfLengths += length (s); 345 } 346 t = Melder_stopwatch (); // 72 ns 347 MelderInfo_writeLine (sumOfLengths); 348 } break; 349 case kPraatTests::TIME_SUM: { 350 integer size = Melder_atoi (arg2); 351 autoVEC x = randomGauss_VEC (size, 0.0, 1.0); 352 double z = 0.0; 353 for (int64 i = 1; i <= n; i ++) { 354 double sum = NUMsum (x.get()); 355 z += sum; 356 } 357 t = Melder_stopwatch () / size; // for size == 100: 0.31 ns 358 MelderInfo_writeLine (z); 359 } break; 360 case kPraatTests::TIME_MEAN: { 361 integer size = Melder_atoi (arg2); 362 autoVEC x = randomGauss_VEC (size, 0.0, 1.0); 363 double z = 0.0; 364 for (int64 i = 1; i <= n; i ++) { 365 double sum = NUMmean (x.get()); 366 z += sum; 367 } 368 t = Melder_stopwatch () / size; // for size == 100: 0.34 ns 369 MelderInfo_writeLine (z); 370 } break; 371 case kPraatTests::TIME_STDEV: { 372 integer size = 10000; 373 autoVEC x = randomGauss_VEC (size, 0.0, 1.0); 374 double z = 0.0; 375 for (int64 i = 1; i <= n; i ++) { 376 double stdev = NUMstdev (x.get()); 377 z += stdev; 378 } 379 t = Melder_stopwatch () / size; 380 MelderInfo_writeLine (z); 381 } break; 382 case kPraatTests::TIME_ALLOC: { 383 integer size = Melder_atoi (arg2); 384 for (int64 iteration = 1; iteration <= n; iteration ++) { 385 autoVEC result = raw_VEC (size); 386 for (integer i = 1; i <= size; i ++) 387 result [i] = 0.0; 388 } 389 t = Melder_stopwatch () / size; // 10^0..7: 70/6.9/1.08 / 0.074/0.0074/0.0091 / 0.51/0.00026 ns 390 } break; 391 case kPraatTests::TIME_ALLOC0: { 392 integer size = Melder_atoi (arg2); 393 for (int64 iteration = 1; iteration <= n; iteration ++) 394 autoVEC result = zero_VEC (size); 395 t = Melder_stopwatch () / size; // 10^0..7: 76/7.7/1.23 / 0.165/0.24/0.25 / 1.30/1.63 ns 396 } break; 397 case kPraatTests::TIME_ZERO: { 398 integer size = Melder_atoi (arg2); 399 autoVEC result = raw_VEC (size); 400 double z = 0.0; 401 for (int64 iteration = 1; iteration <= n; iteration ++) { 402 for (integer i = 1; i <= size; i ++) 403 result [i] = (double) i; 404 z += result [size - 1]; 405 } 406 t = Melder_stopwatch () / size; 407 MelderInfo_writeLine (z); 408 } break; 409 case kPraatTests::TIME_MALLOC: { 410 integer size = Melder_atoi (arg2); 411 double value = Melder_atof (arg3); 412 double z = 0.0; 413 for (int64 iteration = 1; iteration <= n; iteration ++) { 414 double *result = (double *) malloc (sizeof (double) * (size_t) size); 415 for (integer i = 0; i < size; i ++) 416 result [i] = value; 417 z += result [size / 2]; 418 free (result); 419 } 420 t = Melder_stopwatch () / size; 421 MelderInfo_writeLine (z); 422 } break; 423 case kPraatTests::TIME_CALLOC: { 424 integer size = Melder_atoi (arg2); 425 double z = 0.0; 426 for (integer iteration = 1; iteration <= n; iteration ++) { 427 double *result = (double *) calloc (sizeof (double), (size_t) size); 428 z += result [size / 2]; 429 free (result); 430 } 431 t = Melder_stopwatch () / size; 432 MelderInfo_writeLine (z); 433 } break; 434 case kPraatTests::TIME_ADD: { 435 integer size = Melder_atoi (arg2); 436 autoMAT result = randomGauss_MAT (size, size, 0.0, 1.0); 437 Melder_stopwatch (); 438 for (integer iteration = 1; iteration <= n; iteration ++) 439 result.all() <<= 5.0; 440 t = Melder_stopwatch () / size / size; // 10^0..4: 2.7/0.16/0.24 / 0.38/0.98 441 double sum = NUMsum (result.get()); 442 MelderInfo_writeLine (sum); 443 } break; 444 case kPraatTests::TIME_SIN: { 445 integer size = Melder_atoi (arg2); 446 autoMAT result = randomGauss_MAT (size, size, 0.0, 1.0); 447 Melder_stopwatch (); 448 for (integer iteration = 1; iteration <= n; iteration ++) 449 sin_MAT_inout (result.get()); 450 t = Melder_stopwatch () / size / size; // 10^0..4: 18/5.3/5.2 / 5.3/12 451 double sum = NUMsum (result.get()); 452 MelderInfo_writeLine (sum); 453 } break; 454 case kPraatTests::TIME_VECADD: { 455 integer size = Melder_atoi (arg2); 456 autoVEC x = randomGauss_VEC (size, 0.0, 1.0); 457 autoVEC y = randomGauss_VEC (size, 0.0, 1.0); 458 autoVEC result = raw_VEC (size); 459 Melder_stopwatch (); 460 for (integer iteration = 1; iteration <= n; iteration ++) 461 //add_VEC_out (result.all(), x.all(), y.all()); 462 result.all() <<= x.all() + y.all(); 463 t = Melder_stopwatch () / size; 464 double sum = NUMsum (result.get()); 465 MelderInfo_writeLine (sum); 466 } break; 467 case kPraatTests::TIME_MATMUL: { 468 const integer size1 = Melder_atoi (arg2); 469 integer size2 = Melder_atoi (arg3); 470 integer size3 = Melder_atoi (arg4); 471 if (size2 == 0 || size3 == 0) size3 = size2 = size1; 472 //autoMAT const x = randomGauss_MAT (size1, size2, 0.0, 1.0); 473 //autoMAT const y = randomGauss_MAT (size2, size3, 0.0, 1.0); 474 autoMAT x = constantHH (size1, size2, 10.0); 475 autoMAT y = constantHH (size2, size3, 3.0); 476 autoMAT const result = raw_MAT (size1, size3); 477 //MAT resultget = result.get(); 478 //constMAT xget = x.get(), yget = y.get(); 479 MATVU const result_all = result.all(); 480 constMATVU const x_all = x.all(); 481 constMATVU const y_all = y.all(); 482 Melder_stopwatch (); 483 for (integer iteration = 1; iteration <= n; iteration ++) 484 //MATmul_forceMetal_ (result_all, x_all, y_all); 485 _mul_allowAllocation_MAT_out (result_all, x_all, y_all); 486 const integer numberOfComputations = size1 * size2 * size3 * 2; 487 t = Melder_stopwatch () / numberOfComputations; 488 const double sum = NUMsum (result.get()); 489 const integer numberOfStores = size1 * size2 + size2 * size3 + size1 * size3 + 10000; 490 MelderInfo_writeLine (double (numberOfComputations) / double (numberOfStores), U" computations per store"); 491 MelderInfo_writeLine (sum, U" should be ", size1 * size2 * size3 * 30.0); 492 //Melder_require (NUMequal (result.get(), constantHH (size, size, size * 30.0).get()), U"..."); 493 } break; 494 case kPraatTests::THING_AUTO: { 495 integer numberOfThingsBefore = theTotalNumberOfThings; 496 { 497 Melder_casual (U"1\n"); 498 autoDaata data = Thing_new (Daata); 499 Thing_setName (data.get(), U"hello"); 500 Melder_casual (U"2\n"); 501 testData (data.get()); 502 testAutoData (data.move()); 503 autoDaata data18 = Thing_new (Daata); 504 testAutoData (data18.move()); 505 fprintf (stderr, "3\n"); 506 autoDaata data2 = newAutoData (); 507 fprintf (stderr, "4\n"); 508 autoDaata data3 = newAutoData (); 509 fprintf (stderr, "5\n"); 510 //data2 = data; // disabled l-value copy assignment from same class 511 fprintf (stderr, "6\n"); 512 autoOrdered ordered = Thing_new (Ordered); 513 fprintf (stderr, "7\n"); 514 //data = ordered; // disabled l-value copy assignment from subclass 515 data = ordered.move(); 516 //ordered = data; // disabled l-value copy assignment from superclass 517 //ordered = data.move(); // assignment from superclass to subclass is rightfully refused by compiler 518 fprintf (stderr, "8\n"); 519 data2 = newAutoData (); 520 fprintf (stderr, "8a\n"); 521 autoDaata data5 = newAutoData (); 522 fprintf (stderr, "8b\n"); 523 data2 = data5.move(); 524 fprintf (stderr, "9\n"); 525 //ordered = data; // rightfully refused by compiler 526 fprintf (stderr, "10\n"); 527 //autoOrdered ordered2 = Thing_new (Daata); // rightfully refused by compiler 528 fprintf (stderr, "11\n"); 529 autoDaata data4 = Thing_new (Ordered); // constructor 530 fprintf (stderr, "12\n"); 531 //autoDaata data6 = data4; // disabled l-value copy constructor from same class 532 fprintf (stderr, "13\n"); 533 autoDaata data7 = data4.move(); 534 fprintf (stderr, "14\n"); 535 autoOrdered ordered3 = Thing_new (Ordered); 536 autoDaata data8 = ordered3.move(); 537 fprintf (stderr, "15\n"); 538 //autoDaata data9 = ordered; // disabled l-value copy constructor from subclass 539 fprintf (stderr, "16\n"); 540 autoDaata data10 = data7.move(); 541 fprintf (stderr, "17\n"); 542 autoDaata data11 = Thing_new (Daata); // constructor, move assignment, null destructor 543 fprintf (stderr, "18\n"); 544 data11 = Thing_new (Ordered); 545 fprintf (stderr, "19\n"); 546 testAutoDataRef (data11); 547 fprintf (stderr, "20\n"); 548 //data11 = nullptr; // disabled implicit assignment of pointer to autopointer 549 fprintf (stderr, "21\n"); 550 } 551 integer numberOfThingsAfter = theTotalNumberOfThings; 552 fprintf (stderr, "Number of things: before %ld, after %ld\n", 553 (long_not_integer) numberOfThingsBefore, (long_not_integer) numberOfThingsAfter); 554 #if 0 555 MelderCallback<void,structDaata>::FunctionType f; 556 typedef void (*DataFunc) (Daata); 557 typedef void (*OrderedFunc) (Ordered); 558 DataFunc dataFun; 559 OrderedFunc orderedFun; 560 MelderCallback<void,structDaata> dataFun2 (dataFun); 561 MelderCallback<void,structOrdered> orderedFun2 (orderedFun); 562 MelderCallback<void,structDaata> dataFun3 (orderedFun); 563 //MelderCallback<void,structOrdered> orderedFun3 (dataFun); // rightfully refused by compiler 564 autoDaata data = Thing_new (Daata); 565 dataFun3 (data.get()); 566 #endif 567 { 568 #if 1 569 autoMelderAsynchronous x; 570 //autoMelderAsynchronous y = x; // deleted copy constructor 571 autoMelderAsynchronous y = x.move(); // defined move constructor 572 //x = y; // deleted copy assignment 573 x = y.move(); // defined move assignment 574 autoVEC a; 575 autoVEC b = a.move(); 576 const autoVEC c; 577 const autoVEC d { }; 578 #if 0 579 double *e; 580 const autoVEC f { e, 10 }; 581 #endif 582 { 583 autoVEC g = zero_VEC (100); 584 g [1] = 3.0; 585 VEC gg = g.get(); 586 gg [2] = 4.0; 587 constVEC ggg = g.get(); 588 //ggg [3] = 5.0; // should be refused by the compiler 589 const VEC gggg = g.get(); 590 //gggg [3] = 6.0; // should be refused by the compiler 591 //return f; // call to deleted constructor 592 //gggg.reset(); // should be refused by the compiler 593 //ggg.reset(); // should be refused by the compiler 594 //gg.reset(); 595 } 596 { 597 double x [3], *px = & x [0]; 598 const double *cpx = px; 599 VEC vx (px, 2); 600 constVEC cvx (px, 2); 601 const VEC c_vx (px, 2); 602 double a = c_vx [1]; 603 const double b = c_vx [2]; 604 const double y = 0.0, *py = & y; 605 //VEC vy (py, 0); // ruled out: "No matching constructor for initialization of VEC" (2021-04-03) 606 constVEC cvy { py, 2 }; 607 //const VEC c_vy = VEC (py, 2); // ruled out: "No matching constructor for initialization of VEC" (2021-04-03) 608 const VEC c_vy = (const VEC) VEC (const_cast<double *> (py), 2); 609 double c = c_vy [1]; 610 const double d = c_vy [2]; 611 //VEC c_vy2 = VEC (py, 2); // ruled out: "No matching constructor for initialization of VEC" (2021-04-03) 612 } 613 614 VEC h; 615 autoVEC j; 616 //VEC jh = j; // ruled out: "No viable conversion from autoVEC to VEC" (2021-04-03) 617 //VEC zero = zero_VEC (10); // ruled out: "No viable conversion from autoVEC to VEC" (2021-04-03) 618 //constVEC zero = zero_VEC (10); // ruled out: "No viable conversion from autoVEC to constVEC" (2021-04-03) 619 //j = h; // ruled out: "No viable overloaded '='" (2021-04-03) 620 //h = j; // ruled out: "No viable overloaded '='" (2021-04-03) 621 //h = VEC (j); // ruled out: "No matching conversion for functional-style cast from autoVEC to VEC" (2021-04-03) 622 //VEC & jref = j; // ruled out: "Non-const lvalue reference to type VEC cannot bind to a value of unrelated type autoVEC" (2021-04-03) 623 VEC *ph = & h; 624 autoVEC *pj = & j; 625 //ph = pj; // correctly ruled out: Assigning to 'VEC' from incompatible type 'autoVEC' (2021-04-03) 626 //pj = ph; // correctly ruled out: "Assigning to 'autoVEC *' from incompatible type 'VEC *' (2021-04-03) 627 #endif 628 autoSound sound = Sound_create (1, 0.0, 1.0, 10000, 0.0001, 0.0); 629 sound = Sound_create (1, 0.0, 1.0, 10000, 0.0001, 0.00005); 630 Melder_casual (U"hello ", sound -> dx); 631 autoSTRVEC v; 632 mutablestring32 *pm = v.peek2(); 633 const mutablestring32 *pcm = v.peek2(); 634 //conststring32 *pc = v.peek2(); 635 const conststring32 *pcc = v.peek2(); 636 { 637 vector<double> aa, bb; 638 vector<const double> aac, bbc; 639 //aa = aac; 640 aa = bb; 641 aac = bbc; 642 bbc.cells = bb.cells; 643 } 644 } 645 } break; 646 case kPraatTests::FILEINMEMORYMANAGER_IO: { 647 test_FileInMemoryManager_io (); 648 } break; 649 } 650 MelderInfo_writeLine (Melder_single (n / t * 1e-9), U" Gflop/s"); 651 MelderInfo_close (); 652 return 1; 653 } 654 655 /* More compiler stuff */ 656 #if 1 657 /* 658 Trying out inheritance without encapsulation... 659 Advantage: everything is a method; therefore, the Law of Demeter is satisfied idiomatically 660 Disadvantage: problematic encapsulation 661 */ 662 Thing_declare (Matrix_); 663 Thing_declare (Sound_); 664 Thing_declare (Pitch_); 665 666 /* 667 The following two sets of files have to be included 668 in Pitch_to_Sound.cpp as well as in Sound_to_Pitch.cpp, 669 but can come in either order: 670 */ 671 672 /* 673 Set 1: Pitch.h 674 */ 675 struct structPitch_ : structThing { 676 double f0; 677 autoSound_ toSound (); // anti-encapsulation 678 }; 679 680 /* 681 Set 2: Matrix.h followed by Sound.h 682 */ 683 struct structMatrix_ : structThing { 684 private: double x, y; 685 public: double getX () { return x; } 686 void setX (double newX) { x = newX; } 687 }; 688 struct structSound_ : public structMatrix_ { // the definition of structSound_ requires the prior definition of structMatrix_ 689 autoPitch_ toPitch (); // anti-encapsulation 690 }; 691 692 /* 693 The following two files are independent of each other: 694 */ 695 696 /* 697 Pitch_to_Sound.cpp: 698 #include "Pitch.h" 699 #include "Sound.h" 700 */ 701 autoSound_ structPitch_::toSound () { // this requires the prior definition of structPitch_ and the prior declaration of structSound_ 702 autoSound_ result = autoSound_ (); 703 result -> setX (f0); // this requires the prior definition of structSound_ and structMatrix_ 704 return result; 705 } 706 707 /* 708 Sound_to_Pitch.cpp: 709 #include "Sound.h" 710 #include "Pitch.h" 711 */ 712 autoPitch_ structSound_::toPitch () { // this requires the prior definition of structSound_ and the prior declaration of structPitch_ 713 double x = getX (); // this requires the prior definition of structSound_ and structMatrix_ 714 autoPitch_ result = autoPitch_ (); 715 result -> f0 = x; // this requires the prior definition of structPitch_ 716 return result; 717 } 718 719 #endif 720 721 /* 722 An attempt to not have VEC and constVEC, but VEC and const VEC instead. 723 */ 724 725 class Vec { 726 public: 727 double *at; 728 integer size; 729 const double *const_propagate_at () const { return at; } 730 double *const_propagate_at () { return at; } 731 public: 732 Vec (double *initialAt, integer initialSize) : at (initialAt), size (initialSize) { } 733 double& operator[] (integer index) { return at [index]; } // selected for Vec (1) 734 const double& operator[] (integer index) const { return at [index]; } // selected for const Vec (2) 735 //Vec (Vec& other) : at (other.const_propagate_at()), size (other.size) { }; // can assign Vec to Vec (3) 736 //Vec (Vec&& other) : at (other.at), size (other.size) { }; // can assign Vec to Vec (3) 737 Vec (Vec& other) : at (other.at), size (other.size) { }; // can assign Vec to Vec (3) 738 Vec (const Vec& other) = delete; // cannot assign const Vec to Vec (4) 739 /* unfortunately, this also precludes initializing a *const* Vec from a const Vec */ 740 //Vec (const Vec& other) const = default; // attempt to copy a const Vec to a const Vec, but constructors cannot be const 741 //const Vec (const Vec& other) = default; // attempt to copy a const Vec to a const Vec, but constructors cannot have a return type 742 }; 743 744 static Vec copy (Vec x) { 745 return Vec(x); 746 } 747 748 /*static void tryVec () { 749 Vec x = Vec (nullptr, 0); 750 x [1] = 3.0; 751 double a = x [2]; 752 const Vec cx = Vec (nullptr, 0); 753 //cx [1] = 3.0; // should be refused by compiler, because operator[] returns a const value that cannot be assigned to (2) 754 a = cx [2]; // should be allowed by compiler, because not an assignment (2) 755 const Vec cy = x; // should be allowed (3) 756 //Vec y = cx; // should be refused (4) 757 const Vec cz = copy (x); 758 //cx.at [1] = 3.0; 759 ////const Vec ca = cy; // should be allowed 760 }*/ 761 762 /* End of file Praat_tests.cpp */ 763