(** 63 bit signed integer type *) (* (C) Copyright 2008 Richard W.M. Jones, Red Hat Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *) (** This module deals with creating an efficient 63 bit signed integer type. In OCaml, the basic [int] type is fast because it is unboxed, but it has a different size on 32 and 64 bit platforms (31 and 63 bits respectively). If we want a large integer type we can use the OCaml [int64] type, but that is boxed and hence operations are slow, even on 64 bit platforms. This type gives us a large integer (up to 63 bits, therefore fine for things involving eg. large disk file sizes), but retains efficiency. On 64 bit platforms it degenerates into just a normal [int], hence unboxed and fast. On 32 bit platforms it degenerates to a kind of [int64], which is boxed and slow but hey 32 bit platforms are going the way of all things anyway. The implementation of this type is in the files [int63_on_32.ml] or [int63_on_64.ml] for 32 bit and 64 bit platforms respectively. The appropriate implementation is copied by the Makefile to [int63.ml]. *) (** {2 Type Int63.t} OCaml cross-module inlining means that the compiler gets to inline [int] operations directly and efficiently on 64 bit platforms. However we still need to hide the actual type to prevent people from writing code that accidentally depends on 32/64-bit platform differences. *) type t (** {2 Operators} It is recommended to do: {[ open Int63.Operators ]} in your code so that you get the operators [+^], [-^] .. and the type [int63] directly, and can still use the less frequent functions such as {!Int63.abs} etc. *) module Operators : sig type int63 = t (* For the gory details of the rules of operators, see: * http://caml.inria.fr/pub/docs/manual-ocaml/lex.html *) val ( +^ ) : t -> t -> t val ( -^ ) : t -> t -> t val ( *^ ) : t -> t -> t val ( /^ ) : t -> t -> t val ( %^ ) : t -> t -> t (** Infix arithmetic operators. eg. [a +^ b -^ c] *) val ( <^< ) : t -> int -> t val ( >^> ) : t -> int -> t (** Infix shift left and logical shift right. eg. [~^1 <^< 62] NB: We cannot use two less-than signs or two greater-than signs in a row because that clashes with the symbols used for camlp4 quotations. *) val ( &&^ ) : t -> t -> t val ( ||^ ) : t -> t -> t val ( ^^^ ) : t -> t -> t (** Infix logical and, or and xor operators. eg. [bits &&^ mask] *) val ( ~^ ) : int -> t (** Small integer constants, eg. [~^0] is the constant zero and [~^1] is the constant one. *) val ( ~^~ ) : int -> t (** Small negative integer constants, eg. [~^~1] is the constant minus one. *) end (** {2 Functions} These functions are analogous to the similarly named functions available in the standard library [Int32] and [Int64] modules. *) val zero : t val one : t val minus_one : t (** Some constants. *) val neg : t -> t (** Negate. *) val add : t -> t -> t val sub : t -> t -> t val mul : t -> t -> t val div : t -> t -> t val rem : t -> t -> t (** Arithmetic. *) val succ : t -> t (** Successor. *) val pred : t -> t (** Predecessor. *) val abs : t -> t (** Absolute value. *) val max_int : t (** The constant 2{^62}-1. *) val min_int : t (** The constant -2{^62}. *) val logand : t -> t -> t val logor : t -> t -> t val logxor : t -> t -> t val lognot : t -> t (** Bitwise logical and, or, xor and not. *) val shift_left : t -> int -> t (** Shift the number left by the integer number of bits. *) val shift_right : t -> int -> t (** Arithmetic shift the number right by the integer number of bits. The sign bit is replicated into the vacated bits. *) val shift_right_logical : t -> int -> t (** Logical shift the number right by the integer number of bits. The vacated bits are filled with bit [0] regardless of sign. *) val of_int : int -> t val to_int : t -> int val of_float : float -> t val to_float : t -> float val of_int32 : int32 -> t val to_int32 : t -> int32 val of_int64 : int64 -> t val to_int64 : t -> int64 val of_nativeint : nativeint -> t val to_nativeint : t -> nativeint (** Convert between t and various standard types. *) val of_string : string -> t val to_string : t -> string (** Convert between string. *) val compare : t -> t -> int (** Compare two numbers. *)