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