1 // Copyright (C) 2003 Davis E. King (davis@dlib.net) 2 // License: Boost Software License See LICENSE.txt for the full license. 3 4 #ifdef DLIB_ALL_SOURCE_END 5 #include "dlib_basic_cpp_build_tutorial.txt" 6 #endif 7 8 #ifndef DLIB_ALGs_ 9 #define DLIB_ALGs_ 10 11 // this file contains miscellaneous stuff 12 13 // Give people who forget the -std=c++11 option a reminder 14 #if (defined(__GNUC__) && ((__GNUC__ >= 4 && __GNUC_MINOR__ >= 8) || (__GNUC__ > 4))) || \ 15 (defined(__clang__) && ((__clang_major__ >= 3 && __clang_minor__ >= 4) || (__clang_major__ >= 3))) 16 #if __cplusplus < 201103 17 #error "Dlib requires C++11 support. Give your compiler the -std=c++11 option to enable it." 18 #endif 19 #endif 20 21 #if defined __NVCC__ 22 // Disable the "statement is unreachable" message since it will go off on code that is 23 // actually reachable but just happens to not be reachable sometimes during certain 24 // template instantiations. 25 #pragma diag_suppress code_is_unreachable 26 #endif 27 28 29 #ifdef _MSC_VER 30 31 #if _MSC_VER < 1900 32 #error "dlib versions newer than v19.1 use C++11 and therefore require Visual Studio 2015 or newer." 33 #endif 34 35 // Disable the following warnings for Visual Studio 36 37 // this is to disable the "'this' : used in base member initializer list" 38 // warning you get from some of the GUI objects since all the objects 39 // require that their parent class be passed into their constructor. 40 // In this case though it is totally safe so it is ok to disable this warning. 41 #pragma warning(disable : 4355) 42 43 // This is a warning you get sometimes when Visual Studio performs a Koenig Lookup. 44 // This is a bug in visual studio. It is a totally legitimate thing to 45 // expect from a compiler. 46 #pragma warning(disable : 4675) 47 48 // This is a warning you get from visual studio 2005 about things in the standard C++ 49 // library being "deprecated." I checked the C++ standard and it doesn't say jack 50 // about any of them (I checked the searchable PDF). So this warning is total Bunk. 51 #pragma warning(disable : 4996) 52 53 // This is a warning you get from visual studio 2003: 54 // warning C4345: behavior change: an object of POD type constructed with an initializer 55 // of the form () will be default-initialized. 56 // I love it when this compiler gives warnings about bugs in previous versions of itself. 57 #pragma warning(disable : 4345) 58 59 60 // Disable warnings about conversion from size_t to unsigned long and long. 61 #pragma warning(disable : 4267) 62 63 // Disable warnings about conversion from double to float 64 #pragma warning(disable : 4244) 65 #pragma warning(disable : 4305) 66 67 // Disable "warning C4180: qualifier applied to function type has no meaning; ignored". 68 // This warning happens often in generic code that works with functions and isn't useful. 69 #pragma warning(disable : 4180) 70 71 // Disable "warning C4290: C++ exception specification ignored except to indicate a function is not __declspec(nothrow)" 72 #pragma warning(disable : 4290) 73 74 75 // DNN module uses template-based network declaration that leads to very long 76 // type names. Visual Studio will produce Warning C4503 in such cases. https://msdn.microsoft.com/en-us/library/074af4b6.aspx says 77 // that correct binaries are still produced even when this warning happens, but linker errors from visual studio, if they occur could be confusing. 78 #pragma warning( disable: 4503 ) 79 80 81 #endif 82 83 #ifdef __BORLANDC__ 84 // Disable the following warnings for the Borland Compilers 85 // 86 // These warnings just say that the compiler is refusing to inline functions with 87 // loops or try blocks in them. 88 // 89 #pragma option -w-8027 90 #pragma option -w-8026 91 #endif 92 93 #include <string> // for the exceptions 94 95 #ifdef __CYGWIN__ 96 namespace std 97 { 98 typedef std::basic_string<wchar_t> wstring; 99 } 100 #endif 101 102 #include "platform.h" 103 #include "windows_magic.h" 104 105 106 #include <algorithm> // for std::swap 107 #include <new> // for std::bad_alloc 108 #include <cstdlib> 109 #include <stddef.h> 110 #include <limits> // for std::numeric_limits for is_finite() 111 #include "assert.h" 112 #include "error.h" 113 #include "noncopyable.h" 114 #include "enable_if.h" 115 #include "uintn.h" 116 #include "numeric_constants.h" 117 #include "memory_manager_stateless/memory_manager_stateless_kernel_1.h" // for the default memory manager 118 119 120 121 // ---------------------------------------------------------------------------------------- 122 /*!A _dT !*/ 123 124 template <typename charT> 125 inline charT _dTcast (const char a, const wchar_t b); 126 template <> 127 inline char _dTcast<char> (const char a, const wchar_t ) { return a; } 128 template <> 129 inline wchar_t _dTcast<wchar_t> (const char , const wchar_t b) { return b; } 130 131 template <typename charT> 132 inline const charT* _dTcast ( const char* a, const wchar_t* b); 133 template <> 134 inline const char* _dTcast<char> ( const char* a, const wchar_t* ) { return a; } 135 template <> 136 inline const wchar_t* _dTcast<wchar_t> ( const char* , const wchar_t* b) { return b; } 137 138 139 #define _dT(charT,str) _dTcast<charT>(str,L##str) 140 /*! 141 requires 142 - charT == char or wchar_t 143 - str == a string or character literal 144 ensures 145 - returns the literal in the form of a charT type literal. 146 !*/ 147 148 // ---------------------------------------------------------------------------------------- 149 150 151 152 namespace dlib 153 { 154 155 // ---------------------------------------------------------------------------------------- 156 157 /*!A default_memory_manager 158 159 This memory manager just calls new and delete directly. 160 161 !*/ 162 typedef memory_manager_stateless_kernel_1<char> default_memory_manager; 163 164 // ---------------------------------------------------------------------------------------- 165 166 /*!A swap !*/ 167 // make swap available in the dlib namespace 168 using std::swap; 169 170 // ---------------------------------------------------------------------------------------- 171 172 /*! 173 Here is where I define my return codes. It is 174 important that they all be < 0. 175 !*/ 176 177 enum general_return_codes 178 { 179 TIMEOUT = -1, 180 WOULDBLOCK = -2, 181 OTHER_ERROR = -3, 182 SHUTDOWN = -4, 183 PORTINUSE = -5 184 }; 185 186 // ---------------------------------------------------------------------------------------- 187 square_root(unsigned long value)188 inline unsigned long square_root ( 189 unsigned long value 190 ) 191 /*! 192 requires 193 - value <= 2^32 - 1 194 ensures 195 - returns the square root of value. if the square root is not an 196 integer then it will be rounded up to the nearest integer. 197 !*/ 198 { 199 unsigned long x; 200 201 // set the initial guess for what the root is depending on 202 // how big value is 203 if (value < 3) 204 return value; 205 else if (value < 4096) // 12 206 x = 45; 207 else if (value < 65536) // 16 208 x = 179; 209 else if (value < 1048576) // 20 210 x = 717; 211 else if (value < 16777216) // 24 212 x = 2867; 213 else if (value < 268435456) // 28 214 x = 11469; 215 else // 32 216 x = 45875; 217 218 219 220 // find the root 221 x = (x + value/x)>>1; 222 x = (x + value/x)>>1; 223 x = (x + value/x)>>1; 224 x = (x + value/x)>>1; 225 226 227 228 if (x*x < value) 229 return x+1; 230 else 231 return x; 232 } 233 234 // ---------------------------------------------------------------------------------------- 235 236 template < 237 typename T 238 > 239 void median ( 240 T& one, 241 T& two, 242 T& three 243 ); 244 /*! 245 requires 246 - T implements operator< 247 - T is swappable by a global swap() 248 ensures 249 - #one is the median 250 - #one, #two, and #three is some permutation of one, two, and three. 251 !*/ 252 253 254 template < 255 typename T 256 > median(T & one,T & two,T & three)257 void median ( 258 T& one, 259 T& two, 260 T& three 261 ) 262 { 263 using std::swap; 264 using dlib::swap; 265 266 if ( one < two ) 267 { 268 // one < two 269 if ( two < three ) 270 { 271 // one < two < three : two 272 swap(one,two); 273 274 } 275 else 276 { 277 // one < two >= three 278 if ( one < three) 279 { 280 // three 281 swap(three,one); 282 } 283 } 284 285 } 286 else 287 { 288 // one >= two 289 if ( three < one ) 290 { 291 // three <= one >= two 292 if ( three < two ) 293 { 294 // two 295 swap(two,one); 296 } 297 else 298 { 299 // three 300 swap(three,one); 301 } 302 } 303 } 304 } 305 306 // ---------------------------------------------------------------------------------------- 307 308 namespace relational_operators 309 { 310 template < 311 typename A, 312 typename B 313 > 314 constexpr bool operator> ( 315 const A& a, 316 const B& b 317 ) { return b < a; } 318 319 // --------------------------------- 320 321 template < 322 typename A, 323 typename B 324 > 325 constexpr bool operator!= ( 326 const A& a, 327 const B& b 328 ) { return !(a == b); } 329 330 // --------------------------------- 331 332 template < 333 typename A, 334 typename B 335 > 336 constexpr bool operator<= ( 337 const A& a, 338 const B& b 339 ) { return !(b < a); } 340 341 // --------------------------------- 342 343 template < 344 typename A, 345 typename B 346 > 347 constexpr bool operator>= ( 348 const A& a, 349 const B& b 350 ) { return !(a < b); } 351 352 } 353 354 // ---------------------------------------------------------------------------------------- 355 356 template < 357 typename T 358 > exchange(T & a,T & b)359 void exchange ( 360 T& a, 361 T& b 362 ) 363 /*! 364 This function does the exact same thing that global swap does and it does it by 365 just calling swap. But a lot of compilers have problems doing a Koenig Lookup 366 and the fact that this has a different name (global swap has the same name as 367 the member functions called swap) makes them compile right. 368 369 So this is a workaround but not too ugly of one. But hopefully I get get 370 rid of this in a few years. So this function is already deprecated. 371 372 This also means you should NOT use this function in your own code unless 373 you have to support an old buggy compiler that benefits from this hack. 374 !*/ 375 { 376 using std::swap; 377 using dlib::swap; 378 swap(a,b); 379 } 380 381 // ---------------------------------------------------------------------------------------- 382 383 /*!A is_pointer_type 384 385 This is a template where is_pointer_type<T>::value == true when T is a pointer 386 type and false otherwise. 387 !*/ 388 389 template < 390 typename T 391 > 392 class is_pointer_type 393 { 394 public: 395 enum { value = false }; 396 private: 397 is_pointer_type(); 398 }; 399 400 template < 401 typename T 402 > 403 class is_pointer_type<T*> 404 { 405 public: 406 enum { value = true }; 407 private: 408 is_pointer_type(); 409 }; 410 411 // ---------------------------------------------------------------------------------------- 412 413 /*!A is_const_type 414 415 This is a template where is_const_type<T>::value == true when T is a const 416 type and false otherwise. 417 !*/ 418 419 template <typename T> 420 struct is_const_type 421 { 422 static const bool value = false; 423 }; 424 template <typename T> 425 struct is_const_type<const T> 426 { 427 static const bool value = true; 428 }; 429 template <typename T> 430 struct is_const_type<const T&> 431 { 432 static const bool value = true; 433 }; 434 435 // ---------------------------------------------------------------------------------------- 436 437 /*!A is_reference_type 438 439 This is a template where is_reference_type<T>::value == true when T is a reference 440 type and false otherwise. 441 !*/ 442 443 template <typename T> 444 struct is_reference_type 445 { 446 static const bool value = false; 447 }; 448 449 template <typename T> struct is_reference_type<const T&> { static const bool value = true; }; 450 template <typename T> struct is_reference_type<T&> { static const bool value = true; }; 451 452 // ---------------------------------------------------------------------------------------- 453 454 /*!A is_same_type 455 456 This is a template where is_same_type<T,U>::value == true when T and U are the 457 same type and false otherwise. 458 !*/ 459 460 template < 461 typename T, 462 typename U 463 > 464 class is_same_type 465 { 466 public: 467 enum {value = false}; 468 private: 469 is_same_type(); 470 }; 471 472 template <typename T> 473 class is_same_type<T,T> 474 { 475 public: 476 enum {value = true}; 477 private: 478 is_same_type(); 479 }; 480 481 // ---------------------------------------------------------------------------------------- 482 483 /*!A is_float_type 484 485 This is a template that can be used to determine if a type is one of the built 486 int floating point types (i.e. float, double, or long double). 487 !*/ 488 489 template < typename T > struct is_float_type { const static bool value = false; }; 490 template <> struct is_float_type<float> { const static bool value = true; }; 491 template <> struct is_float_type<double> { const static bool value = true; }; 492 template <> struct is_float_type<long double> { const static bool value = true; }; 493 494 // ---------------------------------------------------------------------------------------- 495 496 /*!A is_convertible 497 498 This is a template that can be used to determine if one type is convertible 499 into another type. 500 501 For example: 502 is_convertible<int,float>::value == true // because ints are convertible to floats 503 is_convertible<int*,float>::value == false // because int pointers are NOT convertible to floats 504 !*/ 505 506 template <typename from, typename to> 507 struct is_convertible 508 { 509 struct yes_type { char a; }; 510 struct no_type { yes_type a[2]; }; 511 static const from& from_helper(); 512 static yes_type test(to); 513 static no_type test(...); 514 const static bool value = sizeof(test(from_helper())) == sizeof(yes_type); 515 }; 516 517 // ---------------------------------------------------------------------------------------- 518 519 struct general_ {}; 520 struct special_ : general_ {}; 521 template<typename> struct int_ { typedef int type; }; 522 523 // ---------------------------------------------------------------------------------------- 524 525 526 /*!A is_same_object 527 528 This is a templated function which checks if both of its arguments are actually 529 references to the same object. It returns true if they are and false otherwise. 530 531 !*/ 532 533 // handle the case where T and U are unrelated types. 534 template < typename T, typename U > 535 typename disable_if_c<is_convertible<T*, U*>::value || is_convertible<U*,T*>::value, bool>::type 536 is_same_object ( 537 const T& a, 538 const U& b 539 ) 540 { 541 return ((void*)&a == (void*)&b); 542 } 543 544 // handle the case where T and U are related types because their pointers can be 545 // implicitly converted into one or the other. E.g. a derived class and its base class. 546 // Or where both T and U are just the same type. This way we make sure that if there is a 547 // valid way to convert between these two pointer types then we will take that route rather 548 // than the void* approach used otherwise. 549 template < typename T, typename U > 550 typename enable_if_c<is_convertible<T*, U*>::value || is_convertible<U*,T*>::value, bool>::type 551 is_same_object ( 552 const T& a, 553 const U& b 554 ) 555 { 556 return (&a == &b); 557 } 558 559 // ---------------------------------------------------------------------------------------- 560 561 /*!A is_unsigned_type 562 563 This is a template where is_unsigned_type<T>::value == true when T is an unsigned 564 scalar type and false when T is a signed scalar type. 565 !*/ 566 template < 567 typename T 568 > 569 struct is_unsigned_type 570 { 571 static const bool value = static_cast<T>((static_cast<T>(0)-static_cast<T>(1))) > 0; 572 }; 573 template <> struct is_unsigned_type<long double> { static const bool value = false; }; 574 template <> struct is_unsigned_type<double> { static const bool value = false; }; 575 template <> struct is_unsigned_type<float> { static const bool value = false; }; 576 577 // ---------------------------------------------------------------------------------------- 578 579 /*!A is_signed_type 580 581 This is a template where is_signed_type<T>::value == true when T is a signed 582 scalar type and false when T is an unsigned scalar type. 583 !*/ 584 template < 585 typename T 586 > 587 struct is_signed_type 588 { 589 static const bool value = !is_unsigned_type<T>::value; 590 }; 591 592 // ---------------------------------------------------------------------------------------- 593 594 template < 595 typename T 596 > 597 class copy_functor 598 { 599 public: 600 void operator() ( 601 const T& source, 602 T& destination 603 ) const 604 { 605 destination = source; 606 } 607 }; 608 609 // ---------------------------------------------------------------------------------------- 610 611 /*!A static_switch 612 613 To use this template you give it some number of boolean expressions and it 614 tells you which one of them is true. If more than one of them is true then 615 it causes a compile time error. 616 617 for example: 618 static_switch<1 + 1 == 2, 4 - 1 == 4>::value == 1 // because the first expression is true 619 static_switch<1 + 1 == 3, 4 == 4>::value == 2 // because the second expression is true 620 static_switch<1 + 1 == 3, 4 == 5>::value == 0 // 0 here because none of them are true 621 static_switch<1 + 1 == 2, 4 == 4>::value == compiler error // because more than one expression is true 622 !*/ 623 624 template < bool v1 = 0, bool v2 = 0, bool v3 = 0, bool v4 = 0, bool v5 = 0, 625 bool v6 = 0, bool v7 = 0, bool v8 = 0, bool v9 = 0, bool v10 = 0, 626 bool v11 = 0, bool v12 = 0, bool v13 = 0, bool v14 = 0, bool v15 = 0 > 627 struct static_switch; 628 629 template <> struct static_switch<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0> { const static int value = 0; }; 630 template <> struct static_switch<1,0,0,0,0,0,0,0,0,0,0,0,0,0,0> { const static int value = 1; }; 631 template <> struct static_switch<0,1,0,0,0,0,0,0,0,0,0,0,0,0,0> { const static int value = 2; }; 632 template <> struct static_switch<0,0,1,0,0,0,0,0,0,0,0,0,0,0,0> { const static int value = 3; }; 633 template <> struct static_switch<0,0,0,1,0,0,0,0,0,0,0,0,0,0,0> { const static int value = 4; }; 634 template <> struct static_switch<0,0,0,0,1,0,0,0,0,0,0,0,0,0,0> { const static int value = 5; }; 635 template <> struct static_switch<0,0,0,0,0,1,0,0,0,0,0,0,0,0,0> { const static int value = 6; }; 636 template <> struct static_switch<0,0,0,0,0,0,1,0,0,0,0,0,0,0,0> { const static int value = 7; }; 637 template <> struct static_switch<0,0,0,0,0,0,0,1,0,0,0,0,0,0,0> { const static int value = 8; }; 638 template <> struct static_switch<0,0,0,0,0,0,0,0,1,0,0,0,0,0,0> { const static int value = 9; }; 639 template <> struct static_switch<0,0,0,0,0,0,0,0,0,1,0,0,0,0,0> { const static int value = 10; }; 640 template <> struct static_switch<0,0,0,0,0,0,0,0,0,0,1,0,0,0,0> { const static int value = 11; }; 641 template <> struct static_switch<0,0,0,0,0,0,0,0,0,0,0,1,0,0,0> { const static int value = 12; }; 642 template <> struct static_switch<0,0,0,0,0,0,0,0,0,0,0,0,1,0,0> { const static int value = 13; }; 643 template <> struct static_switch<0,0,0,0,0,0,0,0,0,0,0,0,0,1,0> { const static int value = 14; }; 644 template <> struct static_switch<0,0,0,0,0,0,0,0,0,0,0,0,0,0,1> { const static int value = 15; }; 645 646 // ---------------------------------------------------------------------------------------- 647 /*!A is_built_in_scalar_type 648 649 This is a template that allows you to determine if the given type is a built 650 in scalar type such as an int, char, float, short, etc. 651 652 For example, is_built_in_scalar_type<char>::value == true 653 For example, is_built_in_scalar_type<std::string>::value == false 654 !*/ 655 656 template <typename T> struct is_built_in_scalar_type { const static bool value = false; }; 657 658 template <> struct is_built_in_scalar_type<float> { const static bool value = true; }; 659 template <> struct is_built_in_scalar_type<double> { const static bool value = true; }; 660 template <> struct is_built_in_scalar_type<long double> { const static bool value = true; }; 661 template <> struct is_built_in_scalar_type<short> { const static bool value = true; }; 662 template <> struct is_built_in_scalar_type<int> { const static bool value = true; }; 663 template <> struct is_built_in_scalar_type<long> { const static bool value = true; }; 664 template <> struct is_built_in_scalar_type<unsigned short> { const static bool value = true; }; 665 template <> struct is_built_in_scalar_type<unsigned int> { const static bool value = true; }; 666 template <> struct is_built_in_scalar_type<unsigned long> { const static bool value = true; }; 667 template <> struct is_built_in_scalar_type<uint64> { const static bool value = true; }; 668 template <> struct is_built_in_scalar_type<int64> { const static bool value = true; }; 669 template <> struct is_built_in_scalar_type<char> { const static bool value = true; }; 670 template <> struct is_built_in_scalar_type<signed char> { const static bool value = true; }; 671 template <> struct is_built_in_scalar_type<unsigned char> { const static bool value = true; }; 672 // Don't define one for wchar_t when using a version of visual studio 673 // older than 8.0 (visual studio 2005) since before then they improperly set 674 // wchar_t to be a typedef rather than its own type as required by the C++ 675 // standard. 676 #if !defined(_MSC_VER) || _NATIVE_WCHAR_T_DEFINED 677 template <> struct is_built_in_scalar_type<wchar_t> { const static bool value = true; }; 678 #endif 679 680 // ---------------------------------------------------------------------------------------- 681 682 template < 683 typename T 684 > 685 typename enable_if<is_built_in_scalar_type<T>,bool>::type is_finite ( 686 const T& value 687 ) 688 /*! 689 requires 690 - value must be some kind of scalar type such as int or double 691 ensures 692 - returns true if value is a finite value (e.g. not infinity or NaN) and false 693 otherwise. 694 !*/ 695 { 696 if (is_float_type<T>::value) 697 return -std::numeric_limits<T>::infinity() < value && value < std::numeric_limits<T>::infinity(); 698 else 699 return true; 700 } 701 702 // ---------------------------------------------------------------------------------------- 703 704 /*!A promote 705 706 This is a template that takes one of the built in scalar types and gives you another 707 scalar type that should be big enough to hold sums of values from the original scalar 708 type. The new scalar type will also always be signed. 709 710 For example, promote<uint16>::type == int32 711 !*/ 712 713 template <typename T, size_t s = sizeof(T)> struct promote; 714 template <typename T> struct promote<T,1> { typedef int32 type; }; 715 template <typename T> struct promote<T,2> { typedef int32 type; }; 716 template <typename T> struct promote<T,4> { typedef int64 type; }; 717 template <typename T> struct promote<T,8> { typedef int64 type; }; 718 719 template <> struct promote<float,sizeof(float)> { typedef double type; }; 720 template <> struct promote<double,sizeof(double)> { typedef double type; }; 721 template <> struct promote<long double,sizeof(long double)> { typedef long double type; }; 722 723 // ---------------------------------------------------------------------------------------- 724 725 /*!A assign_zero_if_built_in_scalar_type 726 727 This function assigns its argument the value of 0 if it is a built in scalar 728 type according to the is_built_in_scalar_type<> template. If it isn't a 729 built in scalar type then it does nothing. 730 !*/ 731 732 template <typename T> inline typename disable_if<is_built_in_scalar_type<T>,void>::type assign_zero_if_built_in_scalar_type (T&){} 733 template <typename T> inline typename enable_if<is_built_in_scalar_type<T>,void>::type assign_zero_if_built_in_scalar_type (T& a){a=0;} 734 735 // ---------------------------------------------------------------------------------------- 736 737 /*!A basic_type 738 739 This is a template that takes a type and strips off any const, volatile, or reference 740 qualifiers and gives you back the basic underlying type. So for example: 741 742 basic_type<const int&>::type == int 743 !*/ 744 745 template <typename T> struct basic_type { typedef T type; }; 746 template <typename T> struct basic_type<const T> { typedef T type; }; 747 template <typename T> struct basic_type<const T&> { typedef T type; }; 748 template <typename T> struct basic_type<volatile const T&> { typedef T type; }; 749 template <typename T> struct basic_type<T&> { typedef T type; }; 750 template <typename T> struct basic_type<volatile T&> { typedef T type; }; 751 template <typename T> struct basic_type<volatile T> { typedef T type; }; 752 template <typename T> struct basic_type<volatile const T> { typedef T type; }; 753 754 // ---------------------------------------------------------------------------------------- 755 756 template <typename T> 757 T put_in_range ( 758 const T& a, 759 const T& b, 760 const T& val 761 ) 762 /*! 763 requires 764 - T is a type that looks like double, float, int, or so forth 765 ensures 766 - if (val is within the range [a,b]) then 767 - returns val 768 - else 769 - returns the end of the range [a,b] that is closest to val 770 !*/ 771 { 772 if (a < b) 773 { 774 if (val < a) 775 return a; 776 else if (val > b) 777 return b; 778 } 779 else 780 { 781 if (val < b) 782 return b; 783 else if (val > a) 784 return a; 785 } 786 787 return val; 788 } 789 790 // overload for double 791 inline double put_in_range(const double& a, const double& b, const double& val) 792 { return put_in_range<double>(a,b,val); } 793 794 // ---------------------------------------------------------------------------------------- 795 796 /*!A tabs 797 798 This is a template to compute the absolute value a number at compile time. 799 800 For example, 801 abs<-4>::value == 4 802 abs<4>::value == 4 803 !*/ 804 805 template <long x, typename enabled=void> 806 struct tabs { const static long value = x; }; 807 template <long x> 808 struct tabs<x,typename enable_if_c<(x < 0)>::type> { const static long value = -x; }; 809 810 // ---------------------------------------------------------------------------------------- 811 812 /*!A tmax 813 814 This is a template to compute the max of two values at compile time 815 816 For example, 817 abs<4,7>::value == 7 818 !*/ 819 820 template <long x, long y, typename enabled=void> 821 struct tmax { const static long value = x; }; 822 template <long x, long y> 823 struct tmax<x,y,typename enable_if_c<(y > x)>::type> { const static long value = y; }; 824 825 // ---------------------------------------------------------------------------------------- 826 827 /*!A tmin 828 829 This is a template to compute the min of two values at compile time 830 831 For example, 832 abs<4,7>::value == 4 833 !*/ 834 835 template <long x, long y, typename enabled=void> 836 struct tmin { const static long value = x; }; 837 template <long x, long y> 838 struct tmin<x,y,typename enable_if_c<(y < x)>::type> { const static long value = y; }; 839 840 // ---------------------------------------------------------------------------------------- 841 842 #define DLIB_MAKE_HAS_MEMBER_FUNCTION_TEST(testname, returnT, funct_name, args) \ 843 struct _two_bytes_##testname { char a[2]; }; \ 844 template < typename T, returnT (T::*funct)args > \ 845 struct _helper_##testname { typedef char type; }; \ 846 template <typename T> \ 847 static char _has_##testname##_helper( typename _helper_##testname<T,&T::funct_name >::type ) { return 0;} \ 848 template <typename T> \ 849 static _two_bytes_##testname _has_##testname##_helper(int) { return _two_bytes_##testname();} \ 850 template <typename T> struct _##testname##workaroundbug { \ 851 const static unsigned long U = sizeof(_has_##testname##_helper<T>('a')); }; \ 852 template <typename T, unsigned long U = _##testname##workaroundbug<T>::U > \ 853 struct testname { static const bool value = false; }; \ 854 template <typename T> \ 855 struct testname<T,1> { static const bool value = true; }; 856 /*!A DLIB_MAKE_HAS_MEMBER_FUNCTION_TEST 857 858 The DLIB_MAKE_HAS_MEMBER_FUNCTION_TEST() macro is used to define traits templates 859 that tell you if a class has a certain member function. For example, to make a 860 test to see if a class has a public method with the signature void print(int) you 861 would say: 862 DLIB_MAKE_HAS_MEMBER_FUNCTION_TEST(has_print, void, print, (int)) 863 864 Then you can check if a class, T, has this method by looking at the boolean value: 865 has_print<T>::value 866 which will be true if the member function is in the T class. 867 868 Note that you can test for member functions taking no arguments by simply passing 869 in empty () like so: 870 DLIB_MAKE_HAS_MEMBER_FUNCTION_TEST(has_print, void, print, ()) 871 This would test for a member of the form: 872 void print(). 873 874 To test for const member functions you would use a statement such as this: 875 DLIB_MAKE_HAS_MEMBER_FUNCTION_TEST(has_print, void, print, ()const) 876 This would test for a member of the form: 877 void print() const. 878 879 To test for const templated member functions you would use a statement such as this: 880 DLIB_MAKE_HAS_MEMBER_FUNCTION_TEST(has_print, void, template print<int>, ()) 881 This would test for a member of the form: 882 template <typename T> void print(). 883 !*/ 884 885 // ---------------------------------------------------------------------------------------- 886 887 /*!A is_function 888 889 This is a template that allows you to determine if the given type is a function. 890 891 For example, 892 void funct(); 893 894 is_built_in_scalar_type<funct>::value == true 895 is_built_in_scalar_type<int>::value == false 896 !*/ 897 898 template <typename T> struct is_function { static const bool value = false; }; 899 template <typename T> 900 struct is_function<T (void)> { static const bool value = true; }; 901 template <typename T, typename A0> 902 struct is_function<T (A0)> { static const bool value = true; }; 903 template <typename T, typename A0, typename A1> 904 struct is_function<T (A0, A1)> { static const bool value = true; }; 905 template <typename T, typename A0, typename A1, typename A2> 906 struct is_function<T (A0, A1, A2)> { static const bool value = true; }; 907 template <typename T, typename A0, typename A1, typename A2, typename A3> 908 struct is_function<T (A0, A1, A2, A3)> { static const bool value = true; }; 909 template <typename T, typename A0, typename A1, typename A2, typename A3, typename A4> 910 struct is_function<T (A0, A1, A2, A3, A4)> { static const bool value = true; }; 911 template <typename T, typename A0, typename A1, typename A2, typename A3, typename A4, 912 typename A5> 913 struct is_function<T (A0,A1,A2,A3,A4,A5)> { static const bool value = true; }; 914 template <typename T, typename A0, typename A1, typename A2, typename A3, typename A4, 915 typename A5, typename A6> 916 struct is_function<T (A0,A1,A2,A3,A4,A5,A6)> { static const bool value = true; }; 917 template <typename T, typename A0, typename A1, typename A2, typename A3, typename A4, 918 typename A5, typename A6, typename A7> 919 struct is_function<T (A0,A1,A2,A3,A4,A5,A6,A7)> { static const bool value = true; }; 920 template <typename T, typename A0, typename A1, typename A2, typename A3, typename A4, 921 typename A5, typename A6, typename A7, typename A8> 922 struct is_function<T (A0,A1,A2,A3,A4,A5,A6,A7,A8)> { static const bool value = true; }; 923 template <typename T, typename A0, typename A1, typename A2, typename A3, typename A4, 924 typename A5, typename A6, typename A7, typename A8, typename A9> 925 struct is_function<T (A0,A1,A2,A3,A4,A5,A6,A7,A8,A9)> { static const bool value = true; }; 926 927 928 template <typename T> class funct_wrap0 929 { 930 public: 931 funct_wrap0(T (&f_)()):f(f_){} 932 T operator()() const { return f(); } 933 private: 934 T (&f)(); 935 }; 936 template <typename T, typename A0> class funct_wrap1 937 { 938 public: 939 funct_wrap1(T (&f_)(A0)):f(f_){} 940 T operator()(A0 a0) const { return f(a0); } 941 private: 942 T (&f)(A0); 943 }; 944 template <typename T, typename A0, typename A1> class funct_wrap2 945 { 946 public: 947 funct_wrap2(T (&f_)(A0,A1)):f(f_){} 948 T operator()(A0 a0, A1 a1) const { return f(a0,a1); } 949 private: 950 T (&f)(A0,A1); 951 }; 952 template <typename T, typename A0, typename A1, typename A2> class funct_wrap3 953 { 954 public: 955 funct_wrap3(T (&f_)(A0,A1,A2)):f(f_){} 956 T operator()(A0 a0, A1 a1, A2 a2) const { return f(a0,a1,a2); } 957 private: 958 T (&f)(A0,A1,A2); 959 }; 960 template <typename T, typename A0, typename A1, typename A2, typename A3> class funct_wrap4 961 { 962 public: 963 funct_wrap4(T (&f_)(A0,A1,A2,A3)):f(f_){} 964 T operator()(A0 a0, A1 a1, A2 a2, A3 a3) const { return f(a0,a1,a2,a3); } 965 private: 966 T (&f)(A0,A1,A2,A3); 967 }; 968 template <typename T, typename A0, typename A1, typename A2, typename A3, typename A4> class funct_wrap5 969 { 970 public: 971 funct_wrap5(T (&f_)(A0,A1,A2,A3,A4)):f(f_){} 972 T operator()(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) const { return f(a0,a1,a2,a3,a4); } 973 private: 974 T (&f)(A0,A1,A2,A3,A4); 975 }; 976 977 /*!A wrap_function 978 979 This is a template that allows you to turn a global function into a 980 function object. The reason for this template's existence is so you can 981 do stuff like this: 982 983 template <typename T> 984 void call_funct(const T& funct) 985 { cout << funct(); } 986 987 std::string test() { return "asdfasf"; } 988 989 int main() 990 { 991 call_funct(wrap_function(test)); 992 } 993 994 The above code doesn't work right on some compilers if you don't 995 use wrap_function. 996 !*/ 997 998 template <typename T> 999 funct_wrap0<T> wrap_function(T (&f)()) { return funct_wrap0<T>(f); } 1000 template <typename T, typename A0> 1001 funct_wrap1<T,A0> wrap_function(T (&f)(A0)) { return funct_wrap1<T,A0>(f); } 1002 template <typename T, typename A0, typename A1> 1003 funct_wrap2<T,A0,A1> wrap_function(T (&f)(A0, A1)) { return funct_wrap2<T,A0,A1>(f); } 1004 template <typename T, typename A0, typename A1, typename A2> 1005 funct_wrap3<T,A0,A1,A2> wrap_function(T (&f)(A0, A1, A2)) { return funct_wrap3<T,A0,A1,A2>(f); } 1006 template <typename T, typename A0, typename A1, typename A2, typename A3> 1007 funct_wrap4<T,A0,A1,A2,A3> wrap_function(T (&f)(A0, A1, A2, A3)) { return funct_wrap4<T,A0,A1,A2,A3>(f); } 1008 template <typename T, typename A0, typename A1, typename A2, typename A3, typename A4> 1009 funct_wrap5<T,A0,A1,A2,A3,A4> wrap_function(T (&f)(A0, A1, A2, A3, A4)) { return funct_wrap5<T,A0,A1,A2,A3,A4>(f); } 1010 1011 // ---------------------------------------------------------------------------------------- 1012 1013 template <unsigned long bSIZE> 1014 class stack_based_memory_block : noncopyable 1015 { 1016 /*! 1017 WHAT THIS OBJECT REPRESENTS 1018 This object is a simple container for a block of memory 1019 of bSIZE bytes. This memory block is located on the stack 1020 and properly aligned to hold any kind of object. 1021 !*/ 1022 public: 1023 static const unsigned long size = bSIZE; 1024 1025 stack_based_memory_block(): data(mem.data) {} 1026 1027 void* get () { return data; } 1028 /*! 1029 ensures 1030 - returns a pointer to the block of memory contained in this object 1031 !*/ 1032 1033 const void* get () const { return data; } 1034 /*! 1035 ensures 1036 - returns a pointer to the block of memory contained in this object 1037 !*/ 1038 1039 private: 1040 1041 // You obviously can't have a block of memory that has zero bytes in it. 1042 COMPILE_TIME_ASSERT(bSIZE > 0); 1043 1044 union mem_block 1045 { 1046 // All of this garbage is to make sure this union is properly aligned 1047 // (a union is always aligned such that everything in it would be properly 1048 // aligned. So the assumption here is that one of these objects has 1049 // a large enough alignment requirement to satisfy any object this 1050 // block of memory might be cast into). 1051 void* void_ptr; 1052 int integer; 1053 struct { 1054 void (stack_based_memory_block::*callback)(); 1055 stack_based_memory_block* o; 1056 } stuff; 1057 long double more_stuff; 1058 1059 uint64 var1; 1060 uint32 var2; 1061 double var3; 1062 1063 char data[size]; 1064 } mem; 1065 1066 // The reason for having this variable is that doing it this way avoids 1067 // warnings from gcc about violations of strict-aliasing rules. 1068 void* const data; 1069 }; 1070 1071 // ---------------------------------------------------------------------------------------- 1072 1073 template < 1074 typename T, 1075 typename F 1076 > 1077 auto max_scoring_element( 1078 const T& container, 1079 F score_func 1080 ) -> decltype(std::make_pair(*container.begin(), 0.0)) 1081 /*! 1082 requires 1083 - container has .begin() and .end(), allowing it to be enumerated. 1084 - score_func() is a function that takes an element of the container and returns a double. 1085 ensures 1086 - This function finds the element of container that has the largest score, 1087 according to score_func(), and returns a std::pair containing that maximal 1088 element along with the score. 1089 - If the container is empty then make_pair(a default initialized object, -infinity) is returned. 1090 !*/ 1091 { 1092 double best_score = -std::numeric_limits<double>::infinity(); 1093 auto best_i = container.begin(); 1094 for (auto i = container.begin(); i != container.end(); ++i) 1095 { 1096 auto score = score_func(*i); 1097 if (score > best_score) 1098 { 1099 best_score = score; 1100 best_i = i; 1101 } 1102 } 1103 1104 using item_type = typename std::remove_reference<decltype(*best_i)>::type; 1105 1106 if (best_i == container.end()) 1107 return std::make_pair(item_type(), best_score); 1108 else 1109 return std::make_pair(*best_i, best_score); 1110 } 1111 1112 // ---------------------------------------------------------------------------------------- 1113 1114 template < 1115 typename T, 1116 typename F 1117 > 1118 auto min_scoring_element( 1119 const T& container, 1120 F score_func 1121 ) -> decltype(std::make_pair(*container.begin(), 0.0)) 1122 /*! 1123 requires 1124 - container has .begin() and .end(), allowing it to be enumerated. 1125 - score_func() is a function that takes an element of the container and returns a double. 1126 ensures 1127 - This function finds the element of container that has the smallest score, 1128 according to score_func(), and returns a std::pair containing that minimal 1129 element along with the score. 1130 - If the container is empty then make_pair(a default initialized object, infinity) is returned. 1131 !*/ 1132 { 1133 double best_score = std::numeric_limits<double>::infinity(); 1134 auto best_i = container.begin(); 1135 for (auto i = container.begin(); i != container.end(); ++i) 1136 { 1137 auto score = score_func(*i); 1138 if (score < best_score) 1139 { 1140 best_score = score; 1141 best_i = i; 1142 } 1143 } 1144 1145 using item_type = typename std::remove_reference<decltype(*best_i)>::type; 1146 1147 if (best_i == container.end()) 1148 return std::make_pair(item_type(), best_score); 1149 else 1150 return std::make_pair(*best_i, best_score); 1151 } 1152 1153 // ---------------------------------------------------------------------------------------- 1154 1155 } 1156 1157 #endif // DLIB_ALGs_ 1158 1159