#line 281 "/home/travis/build/felix-lang/felix/src/packages/numbers.fdoc"
  
  typedef fun integral_promotion: TYPE -> TYPE =
    | #tiny => int
    | #utiny => int
    | #short => int
    | #ushort => int
    | #int => int
    | #uint => uint
    | #long => long
    | #ulong => ulong
    | #vlong => vlong
    | #uvlong => uvlong
  ;
  
  #line 297 "/home/travis/build/felix-lang/felix/src/packages/numbers.fdoc"
  open class Tiny
  {
    ctor tiny: string = "static_cast<#0>(::std::atoi($1.c_str()))" requires Cxx_headers::cstdlib;
    ctor[T in reals] tiny: T = "static_cast<#0>($1)/*int.flx: ctor*/";
  }
  
  open class Short
  {
    ctor short: string = "static_cast<#0>(::std::atoi($1.c_str()))" requires Cxx_headers::cstdlib;
    ctor[T in reals] short: T = "static_cast<#0>($1)/*int.flx: ctor*/";
  }
  
  open class Int
  {
    ctor int: string = "static_cast<#0>(::std::atoi($1.c_str()))" requires Cxx_headers::cstdlib;
    ctor[T in reals] int: T = "static_cast<#0>($1)/*int.flx: ctor*/";
    ctor int : int = "($1)/*int.flx: ctor int IDENT*/";
    // special hack
    ctor int(x:bool)=> match x with | true => 1 | false => 0 endmatch;
  }
  
  open class Long
  {
    ctor long: string = "static_cast<#0>(::std::atoi($1.c_str()))" requires Cxx_headers::cstdlib;
    ctor[T in reals] long: T = "static_cast<#0>($1)/*int.flx: ctor*/";
  }
  
  open class Vlong
  {
    ctor vlong: string = "static_cast<#0>(::std::atoi($1.c_str()))" requires Cxx_headers::cstdlib;
    ctor[T in reals] vlong: T = "static_cast<#0>($1)/*int.flx: ctor*/";
  }
  
  open class Utiny
  {
    ctor utiny: string = "static_cast<#0>(::std::atoi($1.c_str()))" requires Cxx_headers::cstdlib;
    ctor[T in reals] utiny: T = "static_cast<#0>($1)/*int.flx: ctor*/";
  }
  
  open class Ushort
  {
    ctor ushort: string = "static_cast<#0>(::std::atoi($1.c_str()))" requires Cxx_headers::cstdlib;
    ctor[T in reals] ushort: T = "static_cast<#0>($1)/*int.flx: ctor*/";
  }
  
  open class Uint
  {
    ctor uint: string = "static_cast<#0>(::std::atoi($1.c_str()))" requires Cxx_headers::cstdlib;
    ctor[T in reals] uint: T = "static_cast<#0>($1)/*int.flx: ctor*/";
  }
  
  open class Ulong
  {
    ctor ulong: string = "static_cast<#0>(::std::atoi($1.c_str()))" requires Cxx_headers::cstdlib;
    ctor[T in reals] ulong: T = "static_cast<#0>($1)/*int.flx: ctor*/";
  }
  
  open class Uvlong
  {
    ctor uvlong: string = "static_cast<#0>(::std::atoi($1.c_str()))" requires Cxx_headers::cstdlib;
    ctor[T in reals] uvlong: T = "static_cast<#0>($1)/*int.flx: ctor*/";
  }
  
  open class Int8
  {
    ctor int8: string = "static_cast<#0>(::std::atoi($1.c_str()))" requires Cxx_headers::cstdlib;
    ctor[T in reals] int8: T = "static_cast<#0>($1)/*int.flx: ctor*/";
  }
  
  open class Int16
  {
    ctor int16: string = "static_cast<#0>(::std::atoi($1.c_str()))" requires Cxx_headers::cstdlib;
    ctor[T in reals] int16: T = "static_cast<#0>($1)/*int.flx: ctor*/";
  }
  
  open class Int32
  {
    ctor int32: string = "static_cast<#0>(::std::atoi($1.c_str()))" requires Cxx_headers::cstdlib;
    ctor[T in reals] int32: T = "static_cast<#0>($1)/*int.flx: ctor*/";
  }
  
  open class Int64
  {
    ctor int64: string = "static_cast<#0>(::std::atoi($1.c_str()))" requires Cxx_headers::cstdlib;
    ctor[T in reals] int64: T = "static_cast<#0>($1)/*int.flx: ctor*/";
  }
  
  open class Uint8
  {
    ctor uint8: string = "static_cast<#0>(::std::atoi($1.c_str()))" requires Cxx_headers::cstdlib;
    ctor[T in reals] uint8: T = "static_cast<#0>($1)/*int.flx: ctor*/";
  }
  
  open class Uint16
  {
    ctor uint16: string = "static_cast<#0>(::std::atoi($1.c_str()))" requires Cxx_headers::cstdlib;
    ctor[T in reals] uint16: T = "static_cast<#0>($1)/*int.flx: ctor*/";
  }
  
  open class Uint32
  {
    ctor uint32: string = "static_cast<#0>(::std::atoi($1.c_str()))" requires Cxx_headers::cstdlib;
    ctor[T in reals] uint32: T = "static_cast<#0>($1)/*int.flx: ctor*/";
  }
  
  open class Uint64
  {
    ctor uint64: string = "static_cast<#0>(::std::atoi($1.c_str()))" requires Cxx_headers::cstdlib;
    ctor[T in reals] uint64: T = "static_cast<#0>($1)/*int.flx: ctor*/";
  }
  
  open class Size
  {
    ctor size: string = "static_cast<#0>(::std::atoi($1.c_str()))" requires Cxx_headers::cstdlib;
    ctor[T in reals] size: T = "static_cast<#0>($1)/*int.flx: ctor size from #0*/";
    ctor size: size = "($1)/*int.flx: ctor size IDENT*/";
  
    // special overrides so s.len - 1 works
    fun - : size * int -> size = "$1-$2";
    fun + : size * int -> size = "$1+$2";
  }
  
  open class Ptrdiff
  {
    ctor ptrdiff: string = "static_cast<#0>(::std::atoi($1.c_str()))" requires Cxx_headers::cstdlib;
    ctor[T in reals] ptrdiff: T = "static_cast<#0>($1)/*int.flx: ctor*/";
  }
  
  open class Intptr
  {
    ctor intptr: string = "static_cast<#0>(::std::atoi($1.c_str()))" requires Cxx_headers::cstdlib;
    ctor[T in reals] intptr: T = "static_cast<#0>($1)/*int.flx: ctor*/";
  }
  
  open class Uintptr
  {
    ctor uintptr: string = "static_cast<#0>(::std::atoi($1.c_str()))" requires Cxx_headers::cstdlib;
    ctor[T in reals] uintptr: T = "static_cast<#0>($1)/*int.flx: ctor*/";
  }
  
  open class Intmax
  {
    ctor intmax: string = "static_cast<#0>(::std::atoi($1.c_str()))" requires Cxx_headers::cstdlib;
    ctor[T in reals] intmax: T = "static_cast<#0>($1)/*int.flx: ctor*/";
  }
  
  open class Uintmax
  {
    ctor uintmax: string = "static_cast<#0>(::std::atoi($1.c_str()))" requires Cxx_headers::cstdlib;
    ctor[T in reals] uintmax: T = "static_cast<#0>($1)/*int.flx: ctor*/";
  }
  
  
  #line 452 "/home/travis/build/felix-lang/felix/src/packages/numbers.fdoc"
  instance Str[tiny] {
    fun str: tiny -> string = "::flx::rtl::strutil::str<int>($1)" requires package "flx_strutil";
  }
  
  instance Str[utiny] {
    fun str: utiny -> string = "::flx::rtl::strutil::str<unsigned int>($1)" requires package "flx_strutil";
  }
  
  instance
  [
    T in
      short \(\cup\) ushort \(\cup\) int \(\cup\) uint \(\cup\) long \(\cup\) ulong \(\cup\) vlong \(\cup\) uvlong \(\cup\)
      exact_ints \(\cup\) weird_sints \(\cup\) weird_uints
  ]
  Str[T]
  {
    fun str: T -> string = "::flx::rtl::strutil::str<#1>($1)" requires package "flx_strutil";
  }
  
  #line 473 "/home/travis/build/felix-lang/felix/src/packages/numbers.fdoc"
  instance Repr[tiny]   { fun repr[with Str[tiny]]   (t:tiny)   : string => (str t) + "t";  }
  instance Repr[short]  { fun repr[with Str[short]]  (t:short)  : string => (str t) + "s";  }
  instance Repr[int]   { fun repr[with Str[int]]   (t:int)   : string => (str t) + "";  }
  instance Repr[long]   { fun repr[with Str[long]]   (t:long)   : string => (str t) + "l";  }
  instance Repr[vlong]  { fun repr[with Str[vlong]]  (t:vlong)  : string => (str t) + "v";  }
  instance Repr[int8]  { fun repr[with Str[int8]]  (t:int8)  : string => (str t) + "i8";  }
  instance Repr[int16]  { fun repr[with Str[int16]]  (t:int16)  : string => (str t) + "i16";  }
  instance Repr[int32]  { fun repr[with Str[int32]]  (t:int32)  : string => (str t) + "i32";  }
  instance Repr[int64]  { fun repr[with Str[int64]]  (t:int64)  : string => (str t) + "i64";  }
  instance Repr[intmax]  { fun repr[with Str[intmax]]  (t:intmax)  : string => (str t) + "j";  }
  instance Repr[intptr]  { fun repr[with Str[intptr]]  (t:intptr)  : string => (str t) + "p";  }
  instance Repr[ptrdiff]  { fun repr[with Str[ptrdiff]]  (t:ptrdiff)  : string => (str t) + "d";  }
  
  instance Repr[utiny]  { fun repr[with Str[utiny]]  (t:utiny)  : string => (str t) + "ut"; }
  instance Repr[ushort] { fun repr[with Str[ushort]] (t:ushort) : string => (str t) + "us"; }
  instance Repr[uint]   { fun repr[with Str[uint]]   (t:uint)   : string => (str t) + "u";  }
  instance Repr[ulong]  { fun repr[with Str[ulong]]  (t:ulong)  : string => (str t) + "ul"; }
  instance Repr[uvlong] { fun repr[with Str[uvlong]] (t:uvlong) : string => (str t) + "uv"; }
  instance Repr[uint8]  { fun repr[with Str[uint8]]  (t:uint8)  : string => (str t) + "u8";  }
  instance Repr[uint16]  { fun repr[with Str[uint16]]  (t:uint16)  : string => (str t) + "u16";  }
  instance Repr[uint32]  { fun repr[with Str[uint32]]  (t:uint32)  : string => (str t) + "u32";  }
  instance Repr[uint64]  { fun repr[with Str[uint64]]  (t:uint64)  : string => (str t) + "u64";  }
  instance Repr[size]  { fun repr[with Str[size]]  (t:size)  : string => (str t) + "uz";  }
  instance Repr[uintmax]  { fun repr[with Str[uintmax]]  (t:uintmax)  : string => (str t) + "uj";  }
  instance Repr[uintptr]  { fun repr[with Str[uintptr]]  (t:uintptr)  : string => (str t) + "up";  }
  
  
  #line 502 "/home/travis/build/felix-lang/felix/src/packages/numbers.fdoc"
  instance[t in ints] Addgrp[t] {}
  instance[t in ints] Ring[t] {}
  instance[t in ints] MultSemi1[t] {}
  instance[t in ints] Dring[t] {}
  
  instance [t in uints] Bits [t] {
    fun \^ : t * t -> t = "(?1)($1^$2)";
    fun \| : t * t -> t = "(?1)($1|$2)";
    fun \& : t * t -> t = "(?1)($1&$2)";
  
    // note: the cast is essential to ensure ~1tu is 254tu
    fun ~ : t -> t = "(?1)~$1";
    proc ^= : &t * t = "*$1^=$2;";
    proc |= : &t * t = "*$1|=$2;";
    proc &= : &t * t = "*$1&=$2;";
  }
  
  instance[t in ints] Forward[t] {
    fun succ: t -> t = "$1+1";
    proc pre_incr: &t = "++*$1;";
    proc post_incr: &t = "(*$1)++;";
  }
  
  instance[t in ints] Bidirectional[t] {
    fun pred: t -> t = "$1-1";
    proc pre_decr: &t = "--*$1;";
    proc post_decr: &t = "(*$1)--;";
  }
  
  instance[t in ints] Integer[t] {
    fun << : t * t -> t = "$1<<$2";
    fun >> : t * t -> t = "$1>>$2";
  }
  
  #line 538 "/home/travis/build/felix-lang/felix/src/packages/numbers.fdoc"
  instance[t in sints] Signed_integer[t] {
    fun sgn: t -> int = "$1<0??-1:$1>0??1:0";
    fun abs: t -> t = "$1<0??-$1:$1";
  }
  
  #line 545 "/home/travis/build/felix-lang/felix/src/packages/numbers.fdoc"
  instance[t in uints] Unsigned_integer[t] {}
  
  #line 549 "/home/travis/build/felix-lang/felix/src/packages/numbers.fdoc"
  //open[T in sints] Signed_integer[T];
  open Signed_integer[tiny];
  open Signed_integer[short];
  open Signed_integer[int];
  open Signed_integer[long];
  open Signed_integer[vlong];
  open Signed_integer[int8];
  open Signed_integer[int16];
  open Signed_integer[int32];
  open Signed_integer[int64];
  open Signed_integer[intmax];
  open Signed_integer[ptrdiff];
  open Signed_integer[intptr];
  
  //open[T in uints] Unsigned_integer[T];
  open Unsigned_integer[utiny];
  open Unsigned_integer[ushort];
  open Unsigned_integer[uint];
  open Unsigned_integer[ulong];
  open Unsigned_integer[uvlong];
  open Unsigned_integer[uint8];
  open Unsigned_integer[uint16];
  open Unsigned_integer[uint32];
  open Unsigned_integer[uint64];
  open Unsigned_integer[uintmax];
  open Unsigned_integer[size];
  open Unsigned_integer[uintptr];