new fortune
[feisty_meow.git] / nucleus / library / basis / functions.h
1 #ifndef FUNCTIONS_GROUP
2 #define FUNCTIONS_GROUP
3
4 /*****************************************************************************\
5 *                                                                             *
6 *  Name   : functions                                                         *
7 *  Author : Chris Koeritz                                                     *
8 *                                                                             *
9 *******************************************************************************
10 * Copyright (c) 1991-$now By Author.  This program is free software; you can  *
11 * redistribute it and/or modify it under the terms of the GNU General Public  *
12 * License as published by the Free Software Foundation; either version 2 of   *
13 * the License or (at your option) any later version.  This is online at:      *
14 *     http://www.fsf.org/copyleft/gpl.html                                    *
15 * Please send any updates to: fred@gruntose.com                               *
16 \*****************************************************************************/
17
18 /*! @file functions.h
19   Provides a set of useful mini-functions.
20 */
21
22 #include "definitions.h"
23
24 namespace basis {
25
26 template <class type> type maximum(type a, type b)
27         { return (a > b)? a : b; }
28   //!< minimum returns the lesser of two values.
29 template <class type> type minimum(type a, type b)
30         { return (a < b)? a : b; }
31   //!< maximum returns the greater of two values.
32
33 template <class type> type absolute_value(type a)
34         { return (a >= 0)? a : -a; }
35   //!< Returns a if a is non-negative, and returns -a otherwise.
36
37 //////////////
38
39 template <class type> bool positive(const type &a) { return a > 0; }
40   //!< positive returns true if "a" is greater than zero, or false otherwise.
41 template <class type> bool non_positive(const type a) { return a <= 0; }
42   //!< non_positive returns true if "a" is less than or equal to zero.
43 template <class type> bool negative(const type &a) { return a < 0; }
44   //!< negative returns true if "a" is less than zero.
45 template <class type> bool non_negative(const type &a) { return a >= 0; }
46   //!< non_negative returns true if "a" is greater than or equal to zero.
47
48 //////////////
49
50 // the following comparisons are borrowed from the STL.  they provide the full set of comparison
51 // operators for any object that implements the equalizable and orderable base classes.
52 template <class T1, class T2>
53 bool operator != (const T1 &x, const T2 &y) { return !(x == y); }
54
55 template <class T1, class T2>
56 bool operator > (const T1 &x, const T2 &y) { return y < x; }
57
58 template <class T1, class T2>
59 bool operator <= (const T1 &x, const T2 &y) { return !(y < x); }
60
61 template <class T1, class T2>
62 bool operator >= (const T1 &x, const T2 &y) { return !(x < y); }
63
64 //////////////
65
66 //! dynamically converts a type to a target type, or throws an exception if it cannot.
67 template <class target_type, class source_type>
68 target_type *cast_or_throw(source_type &to_cast, const target_type &ignored)
69 {
70 //  if (!&ignored) {}  // do nothing.
71   target_type *cast = dynamic_cast<target_type *>(&to_cast);
72   if (!cast) throw "error: casting problem, unknown RTTI cast.";
73   return cast;
74 }
75
76 //! const version of the cast_or_throw template.
77 template <class target_type, class source_type>
78 const target_type *cast_or_throw(const source_type &to_cast, const target_type &ignored)
79 {
80 // if (!&ignored) {}  // do nothing.
81   const target_type *cast = dynamic_cast<const target_type *>(&to_cast);
82   if (!cast) throw "error: casting problem, unknown RTTI cast.";
83   return cast;
84 }
85
86 //////////////
87
88 template <class type> bool range_check(const type &c, const type &low,
89     const type &high) { return (c >= low) && (c <= high); }
90   //!< Returns true if "c" is between "low" and "high" inclusive.
91
92 template <class type> type square(const type &a) { return a * a; }
93   //!< Returns the square of the object (which is a * a).
94
95 template <class type> void flip_increasing(type &a, type &b)
96       { if (b < a) { type tmp = a; a = b; b = tmp; } }
97   //!< Makes sure that two values are in increasing order (a < b).
98
99 template <class type> void flip_decreasing(type &a, type &b)
100       { if (b > a) { type tmp = a; a = b; b = tmp; } }
101   //!< Makes sure that two values are in decreasing order (a > b).
102
103 template <class type> void swap_values(type &a, type &b)
104       { type tmp = a; a = b; b = tmp; }
105   //!< Exchanges the values held by "a" & "b".
106
107 template <class type> type sign(type a)
108       { if (a < 0) return -1; else if (a > 0) return 1; else return 0; }
109   //!< Returns the numerical sign of a number "a".
110
111 //////////////
112
113 // helpful coding / debugging macros:
114
115 //! deletion with clearing of the pointer.
116 /*! this function simplifies the two step process of deleting a pointer and
117 then clearing it to NULL_POINTER.  this makes debugging a bit easier since an access
118 of NULL_POINTER should always cause a fault, rather than looking like a possibly
119 valid object. */
120 template<class contents>
121 void WHACK(contents * &ptr) { if (ptr) { delete ptr; ptr = NULL_POINTER; } }
122
123 //! Returns an object that is defined statically.
124 /*! Thus the returned object will never be recreated once this function
125 is called within the same scope of memory (within a dynamic library or
126 application).  This is useful for templates that want to have access to a
127 bogus element whose contents don't matter.  NOTE: bogonic is not
128 thread safe! */
129 template <class type> type &bogonic() {
130    static type local_bogon;
131    return local_bogon;
132 }
133
134 //////////////
135
136 template <class type>
137 type number_of_packets(type message_size, type packet_size)
138 { return message_size / packet_size + ((message_size % packet_size) != 0); }
139   //!< Reports number of packets needed given a total size and the packet size.
140   /*!< This returns the number of packets needed to contain a contiguous array
141   of characters with size "message_size" when the number of characters
142   per packet is "packet_size". */
143
144 template <class type>
145 type last_packet_size(type message_size, type packet_size)
146 { return message_size % packet_size? message_size % packet_size : packet_size; }
147   //!< Tells how many bytes are used within last packet.
148   /*< The companion call to number_of_packets; it returns the size of the last
149   packet in the sequence of packets, taking into account the special case
150   where the message_size divides evenly. */
151
152 //////////////
153
154 } //namespace.
155
156 #endif
157