/*
 * Copyright (c) 2008
 * Evan Teran
 *
 * Permission to use, copy, modify, and distribute this software and its
 * documentation for any purpose and without fee is hereby granted, provided
 * that the above copyright notice appears in all copies and that both the
 * copyright notice and this permission notice appear in supporting
 * documentation, and that the same name not be used in advertising or
 * publicity pertaining to distribution of the software without specific,
 * written prior permission. We make no representations about the
 * suitability this software for any purpose. It is provided "as is"
 * without express or implied warranty.
 */

#ifndef MATH_OPS_20051205_H_
#define MATH_OPS_20051205_H_

#include <climits>	// for CHAR_BIT
#include <cstddef>	// for std::size_t

/*
*  the reason why we need the "mask" constant is 
*  because some platforms make >> on negative values
*  arithmetic (which shifts in the sign bit, not 0)
*  using the mask allows this to work with both signed 
*  and unsigned types
*/
template <typename T> inline T rol(T v, int n) {
	static const std::size_t bits(CHAR_BIT * sizeof(T));
	const T mask(~(T(-1) << n));
	return (v << n) | ((v >> (bits - n)) & mask);
}

template <typename T> inline T ror(T v, int n) { return rol(v, -n); }

#endif
