1 #ifndef FUNCTIONS_GROUP
2 #define FUNCTIONS_GROUP
4 /*****************************************************************************\
7 * Author : Chris Koeritz *
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 \*****************************************************************************/
19 Provides a set of useful mini-functions.
22 #include "definitions.h"
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.
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.
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.
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); }
55 template <class T1, class T2>
56 bool operator > (const T1 &x, const T2 &y) { return y < x; }
58 template <class T1, class T2>
59 bool operator <= (const T1 &x, const T2 &y) { return !(y < x); }
61 template <class T1, class T2>
62 bool operator >= (const T1 &x, const T2 &y) { return !(x < y); }
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)
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.";
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)
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.";
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.
92 template <class type> type square(const type &a) { return a * a; }
93 //!< Returns the square of the object (which is a * a).
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).
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).
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".
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".
113 // helpful coding / debugging macros:
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
120 template<class contents>
121 void WHACK(contents * &ptr) { if (ptr) { delete ptr; ptr = NULL_POINTER; } }
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
129 template <class type> type &bogonic() {
130 static type local_bogon;
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". */
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. */