00001 00002 /* 00003 The Extended Integer (XInt) Library 00004 A fast, portable C++ library for multi-precision integer math 00005 Copyright 2010 by Chad Nelson 00006 00007 Distributed under the Boost Software License, Version 1.0. 00008 See accompanying file LICENSE_1_0.txt or copy at 00009 http://www.boost.org/LICENSE_1_0.txt 00010 00011 See http://www.boost.org/libs/xint for library home page. 00012 */ 00013 00020 #ifndef BOOST_INCLUDED_XINT_BASIC_TYPES_HPP 00021 #define BOOST_INCLUDED_XINT_BASIC_TYPES_HPP 00022 00023 #ifdef _WIN32 00024 // Solely for the strong random number generator. 00025 #define STRICT 00026 #define WIN32_LEAN_AND_MEAN 00027 #include <windows.h> 00028 #endif 00029 00030 #ifndef BOOST_PARAMETER_MAX_ARITY 00031 #define BOOST_PARAMETER_MAX_ARITY 6 00032 #endif 00033 00034 #include <string> 00035 #include <vector> 00036 #include <queue> 00037 #include <cstddef> // for std::size_t 00038 #include <cassert> 00039 #include <sstream> 00040 #include <fstream> 00041 #include <ctime> 00042 #include <boost/limits.hpp> 00043 #include <boost/integer.hpp> 00044 #include <boost/cstdint.hpp> 00045 #include <boost/function.hpp> 00046 #include <boost/parameter.hpp> 00047 #include <boost/type_traits.hpp> 00048 #include <boost/scoped_array.hpp> 00049 #include <boost/static_assert.hpp> 00050 00051 // Uncomment this to use Boost.Move, which can improve the speed when using 00052 // extremely large numbers. Note that using options::copy_on_write gives a much 00053 // more noticeable speed improvement. 00054 //#define BOOST_XINT_USE_MOVE 00055 00056 #ifdef BOOST_XINT_USE_MOVE 00057 #include <boost/move/move.hpp> 00058 #define BOOST_XINT_COPY_ASSIGN_REF(type) BOOST_COPY_ASSIGN_REF(type) 00059 #define BOOST_XINT_COPYABLE_AND_MOVABLE(type) BOOST_COPYABLE_AND_MOVABLE(type) 00060 #define BOOST_XINT_RV_REF(type) BOOST_RV_REF(type) 00061 #define BOOST_XINT_MOVE(value) boost::move(value) 00062 #define BOOST_XINT_FORWARD(type, value) boost::forward<type>(value) 00063 #else 00064 template <typename T> class disable_boost_rv_ref: public T { }; 00065 #define BOOST_XINT_COPY_ASSIGN_REF(type) const type& 00066 #define BOOST_XINT_COPYABLE_AND_MOVABLE(type) 00067 #define BOOST_XINT_RV_REF(type) disable_boost_rv_ref<type> 00068 #define BOOST_XINT_MOVE(value) value 00069 #define BOOST_XINT_FORWARD(type, value) value 00070 #endif 00071 00072 namespace boost { 00073 namespace xint { 00074 00088 typedef boost::function<void (const char *file, std::size_t line, const 00089 std::exception& e)> on_exception_t; 00090 00092 typedef boost::function<bool ()> callback_t; 00093 00095 const callback_t no_callback; 00096 00098 typedef std::vector<unsigned char> binary_t; 00099 00102 const std::size_t autobase = (std::numeric_limits<size_t>::max)(); 00103 00105 typedef std::size_t bitsize_t; 00106 00108 template <class T> 00109 class base_divide_t { 00110 public: 00111 base_divide_t() { } 00112 base_divide_t(const T& q, const T& r): quotient(q), remainder(r) { } 00113 base_divide_t(const base_divide_t<T>& copy): 00114 quotient(copy.quotient), remainder(copy.remainder) { } 00115 base_divide_t(BOOST_XINT_RV_REF(base_divide_t) move) { 00116 quotient._swap(move.quotient); remainder._swap(move.remainder); } 00117 00118 base_divide_t& operator=(BOOST_XINT_COPY_ASSIGN_REF(base_divide_t) copy) 00119 { quotient = copy.quotient; remainder = copy.remainder; return *this; } 00120 base_divide_t& operator=(BOOST_XINT_RV_REF(base_divide_t) move) { 00121 using std::swap; 00122 swap(quotient, move.quotient); 00123 swap(remainder, move.remainder); 00124 return *this; } 00125 00126 T quotient, remainder; 00127 00128 private: 00129 BOOST_XINT_COPYABLE_AND_MOVABLE(base_divide_t) 00130 }; 00131 00132 namespace detail { 00134 00140 typedef boost::uintmax_t doubledigit_t; 00141 00147 typedef boost::uint_t<std::numeric_limits<doubledigit_t>::digits / 2>::fast 00148 digit_t; 00149 00151 template <typename T = void> 00152 struct exception_handler { 00153 template <typename E> 00154 static void call(const char *file, std::size_t line, const E& e) { 00155 #ifdef BOOST_XINT_NO_EXCEPTIONS 00156 if (fn) fn(file, line, e); 00157 abort(); 00158 #else 00159 if (fn) fn(file, line, e); 00160 throw e; 00161 #endif 00162 } 00163 00164 static on_exception_t fn; 00165 }; 00166 template <typename T> on_exception_t exception_handler<T>::fn; 00167 00170 const std::size_t minimum_digits = 1; 00171 const std::size_t bits_per_digit = 00172 std::numeric_limits<digit_t>::digits; 00173 const std::size_t digits_in_uintmax = 00174 (std::numeric_limits<boost::uintmax_t>::digits + bits_per_digit - 1) / 00175 bits_per_digit; 00176 const digit_t digit_hibit = (digit_t(1) << (bits_per_digit-1)); 00177 const doubledigit_t doubledigit_hibit = (doubledigit_t(1) << (bits_per_digit*2-1)); 00178 const doubledigit_t digit_overflowbit = (doubledigit_t(1) << bits_per_digit); 00179 const digit_t digit_mask = digit_t(digit_overflowbit-1); 00181 00183 00186 struct magnitude_t { 00187 private: 00188 std::size_t copy_count; 00189 00190 public: 00191 const bool readonly; 00192 const std::size_t max_length; 00193 digit_t digits[minimum_digits]; // Must be last data item, see "struct hack" 00194 00195 magnitude_t(std::size_t max_len = minimum_digits, bool ro = false): 00196 copy_count(0), readonly(ro), max_length(max_len) { } 00197 magnitude_t(std::size_t max_len, bool ro, digit_t init): copy_count(0), 00198 readonly(ro), max_length(max_len) { digits[0] = init; } 00199 magnitude_t& operator=(const magnitude_t&) { throw std::logic_error( 00200 "Can't use operator= on magnitude_t"); } // Here to satisfy MSVC 00201 std::size_t copies() const { return copy_count; } 00202 00203 void inc() { ++copy_count; } 00204 bool dec() { return (--copy_count == 0); } 00205 }; 00206 00207 inline std::size_t bits_to_digits(std::size_t bits) { return (bits + 00208 bits_per_digit - 1) / bits_per_digit; } 00209 00211 } // namespace detail 00212 } // namespace xint 00213 } // namespace boost 00214 00215 #endif // BOOST_INCLUDED_XINT_BASIC_TYPES_HPP
© Copyright Chad Nelson, 2010-2011. Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)