Files
mlpack/fastlib/base/cc.h
T
2008-01-20 06:25:49 +00:00

261 lines
7.5 KiB
C++

// Copyright 2007 Georgia Institute of Technology. All rights reserved.
/**
* @file cc.h
*
* The bare necessities of FASTlib programming in C++.
*/
#ifndef BASE_CC_H
#define BASE_CC_H
#include "common.h"
#include "ccmem.h"
#include <algorithm>
#include <limits>
/** Extract the highly useful min function from the STL. */
using std::min;
/** Extract the highly useful max function from the STL. */
using std::max;
/** NaN value for doubles; check with isnan, not ==. */
extern const double DBL_NAN;
/** NaN value for floats; check with isnanf, not ==. */
extern const float FLT_NAN;
/** Infinity value for doubles; check with isinf, not ==. */
extern const double DBL_INF;
/** Infinity value for floats; check with isinff, not ==. */
extern const float FLT_INF;
/**
* Disables copy construction and assignment.
*
* This will save you needless headaches by preventing accidental
* copying of objects via forgetting to use references in function
* arguments, etc. Instead of odd behavior you will get compiler
* errors. The FASTlib style guide recommends disabling copy
* construction and assignment for classes that do more than store
* data, defining the Copy method in their lieu if appropriate.
*
* Always follow member declaration macros with the appropriate
* visibility label (public, private, or protected).
*
* Example:
* @code
* class MyClass {
* FORBID_ACCIDENTAL_COPIES(MyClass);
* private:
* ...
* };
* @endcode
*/
#define FORBID_ACCIDENTAL_COPIES(C) \
private: \
C (const C &src); \
const C &operator=(const C &src);
/**
* Defines assignment in terms of copy construction for non-recursive
* data structures.
*
* This is faster than the recursion-safe version for shallow data
* structures but about the same otherwise; built-in assignment is
* faster than either. This is safe when the left-hand does not
* contain and is not contained by the right-hand side, i.e. when
* destructing the left does not inadvertantly change the right.
*
* Always follow member declaration macros with the appropriate
* visibility label (public, private, or protected).
*
* @see ASSIGN_VIA_RECURSION_SAFE_COPY_CONSTRUCTION
*/
#define ASSIGN_VIA_COPY_CONSTRUCTION(C) \
public: \
const C &operator=(const C &src) { \
if (likely(this != &src)) { \
this->~C(); \
new(this) C(src); \
} \
return *this; \
}
/**
* Defines assignment in terms of copy construction for recursive data
* structures.
*
* This version of assignment works even when the left-hand side
* contains or is contained by the right-hand side. The left is
* replaced by a snapshot of the right, permitting the right to change
* or be destructed in the process. Due to an additional memcpy at
* the first layer, this method is slower than the recursion-unsafe
* version for shallow data structures but about the same otherwise.
*
* Always follow member declaration macros with the appropriate
* visibility label (public, private, or protected).
*
* @see ASSIGN_VIA_COPY_CONSTRUCTION
*/
#define ASSIGN_VIA_RECURSION_SAFE_COPY_CONSTRUCTION(C) \
public: \
const C &operator=(const C &src) { \
if (likely(this != &src)) { \
char buf[sizeof(C)]; \
mem::BitCopy<C>(buf, this); \
new(this) C(src); \
reinterpret_cast<C *>(buf)->~C(); \
} \
return *this; \
}
/**
* Defines all inequality operators given friended less-than.
*
* Example:
* @code
* class MyClass {
* ...
* friend bool operator<(const MyClass &a, const MyClass &b) {
* return a.v < b.v;
* }
* EXPAND_LESS_THAN(MyClass);
* ...
* };
* @endcode
*
* @see EXPAND_GREATER_THAN, EXPAND_EQUALS, EXPAND_HETERO_LESS_THAN
*/
#define EXPAND_LESS_THAN(C) \
friend bool operator>(C const &b, C const &a) {return a < b;} \
friend bool operator<=(C const &b, C const &a) {return !(a < b);} \
friend bool operator>=(C const &a, C const &b) {return !(a < b);}
/**
* Defines all inequality operators given friended greater-than.
*
* Example:
* @code
* class MyClass {
* ...
* friend bool operator>(const MyClass &a, const MyClass &b) {
* return a.v > b.v;
* }
* EXPAND_GREATER_THAN(MyClass);
* ...
* };
* @endcode
*
* @see EXPAND_LESS_THAN, EXPAND_EQUALS, EXPAND_HETERO_GREATER_THAN
*/
#define EXPAND_GREATER_THAN(C) \
friend bool operator<(C const &b, C const &a) {return a > b;} \
friend bool operator>=(C const &b, C const &a) {return !(a > b);} \
friend bool operator<=(C const &a, C const &b) {return !(a > b);}
/**
* Defines not-equals given friended equals.
*
* Example:
* @code
* class MyClass {
* ...
* friend bool operator==(const MyClass &a, const MyClass &b) {
* return a.v == b.v;
* }
* EXPAND_EQUALS(MyClass);
* ...
* };
* @endcode
*
* @see EXPAND_LESS_THAN, EXPAND_GREATER_THAN, EXPAND_HETERO_EQUALS
*/
#define EXPAND_EQUALS(C) \
friend bool operator!=(C const &a, C const &b) {return !(a == b);}
/**
* Defines several heterogeneous inequality operators given friended
* less-than with the first class on the left.
*
* Use twice, exchanging argument order, to obtain all heterogeneous
* inequalities or use in conjunction with EXPAND_HETERO_GREATER_THAN.
*
* Example:
* @code
* class MyClass {
* ...
* friend bool operator<(const MyClass &a, const int &b) {
* return a.v < b;
* }
* EXPAND_HETERO_LESS_THAN(MyClass, int);
* friend bool operator<(const int &a, const MyClass &b) {
* return a < b.v;
* }
* EXPAND_HETERO_LESS_THAN(int, MyClass);
* ...
* };
* @endcode
*
* @see EXPAND_HETERO_GREATER_THAN, EXPAND_HETERO_EQUALS
*/
#define EXPAND_HETERO_LESS_THAN(C, T) \
friend bool operator>(T const &b, C const &a) {return a < b;} \
friend bool operator<=(T const &b, C const &a) {return !(a < b);} \
friend bool operator>=(C const &a, T const &b) {return !(a < b);}
/**
* Defines several heterogeneous inequality operators given friended
* greater-than with the first class on the left.
*
* Use twice, exchanging argument order, to obtain all heterogeneous
* inequalities or use in conjunction with EXPAND_HETERO_LESS_THAN.
*
* Example:
* @code
* class MyClass {
* ...
* friend bool operator<(const MyClass &a, const int &b) {
* return a.v < b;
* }
* EXPAND_HETERO_LESS_THAN(MyClass, int);
* friend bool operator>(const MyClass &a, const int &b) {
* return a.v > b;
* }
* EXPAND_HETERO_GREATER_THAN(MyClass, int);
* ...
* };
* @endcode
*
* @see EXPAND_HETERO_LESS_THAN, EXPAND_HETERO_EQUALS
*/
#define EXPAND_HETERO_GREATER_THAN(C, T) \
friend bool operator<(T const &b, C const &a) {return a > b;} \
friend bool operator>=(T const &b, C const &a) {return !(a > b);} \
friend bool operator<=(C const &a, T const &b) {return !(a > b);}
/**
* Defines heterogeneus equals with arguments exchanged and both
* not-equals given friended equals with the first class on the left.
*
* Example:
* @code
* class MyClass {
* ...
* friend bool operator==(const MyClass &a, const int &b) {
* return a.v == b;
* }
* EXPAND_HETERO_EQUALS(MyClass, int);
* ...
* };
* @endcode
*
* @see EXPAND_HETERO_LESS_THAN, EXPAND_HETERO_GREATER_THAN
*/
#define EXPAND_HETERO_EQUALS(C, T) \
friend bool operator==(T const &b, C const &a) {return a == b;} \
friend bool operator!=(C const &a, T const &b) {return !(a == b);} \
friend bool operator!=(T const &b, C const &a) {return !(a == b);}
/** Empty object. */
class Empty {};
#endif /* BASE_CC_H */