1 /** 2 * TypeInfo support code. 3 * 4 * Copyright: Copyright Digital Mars 2004 - 2009. 5 * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0). 6 * Authors: Walter Bright 7 */ 8 9 /* Copyright Digital Mars 2004 - 2009. 10 * Distributed under the Boost Software License, Version 1.0. 11 * (See accompanying file LICENSE or copy at 12 * http://www.boost.org/LICENSE_1_0.txt) 13 */ 14 module rt.typeinfo.ti_Aint; 15 16 private import core.stdc.string; 17 18 extern (C) void[] _adSort(void[] a, TypeInfo ti); 19 20 // int[] 21 22 class TypeInfo_Ai : TypeInfo_Array 23 { opEquals(Object o)24 override bool opEquals(Object o) { return TypeInfo.opEquals(o); } 25 toString()26 override string toString() const { return "int[]"; } 27 getHash(scope const void * p)28 override size_t getHash(scope const void* p) @trusted const 29 { 30 // Hash as if unsigned. 31 const s = *cast(const uint[]*)p; 32 return hashOf(s); 33 } 34 equals(in void * p1,in void * p2)35 override bool equals(in void* p1, in void* p2) const 36 { 37 int[] s1 = *cast(int[]*)p1; 38 int[] s2 = *cast(int[]*)p2; 39 40 return s1.length == s2.length && 41 memcmp(cast(void *)s1, cast(void *)s2, s1.length * int.sizeof) == 0; 42 } 43 compare(in void * p1,in void * p2)44 override int compare(in void* p1, in void* p2) const 45 { 46 int[] s1 = *cast(int[]*)p1; 47 int[] s2 = *cast(int[]*)p2; 48 size_t len = s1.length; 49 50 if (s2.length < len) 51 len = s2.length; 52 for (size_t u = 0; u < len; u++) 53 { 54 if (s1[u] < s2[u]) 55 return -1; 56 else if (s1[u] > s2[u]) 57 return 1; 58 } 59 if (s1.length < s2.length) 60 return -1; 61 else if (s1.length > s2.length) 62 return 1; 63 return 0; 64 } 65 inout(TypeInfo)66 override @property inout(TypeInfo) next() inout 67 { 68 return cast(inout)typeid(int); 69 } 70 } 71 72 unittest 73 { 74 int[][] a = [[5,3,8,7], [2,5,3,8,7]]; 75 _adSort(*cast(void[]*)&a, typeid(a[0])); 76 assert(a == [[2,5,3,8,7], [5,3,8,7]]); 77 78 a = [[5,3,8,7], [5,3,8]]; 79 _adSort(*cast(void[]*)&a, typeid(a[0])); 80 assert(a == [[5,3,8], [5,3,8,7]]); 81 } 82 83 unittest 84 { 85 // Issue 13073: original code uses int subtraction which is susceptible to 86 // integer overflow, causing the following case to fail. 87 int[] a = [int.max, int.max]; 88 int[] b = [int.min, int.min]; 89 assert(a > b); 90 assert(b < a); 91 } 92 93 // uint[] 94 95 class TypeInfo_Ak : TypeInfo_Ai 96 { toString()97 override string toString() const { return "uint[]"; } 98 compare(in void * p1,in void * p2)99 override int compare(in void* p1, in void* p2) const 100 { 101 uint[] s1 = *cast(uint[]*)p1; 102 uint[] s2 = *cast(uint[]*)p2; 103 size_t len = s1.length; 104 105 if (s2.length < len) 106 len = s2.length; 107 for (size_t u = 0; u < len; u++) 108 { 109 if (s1[u] < s2[u]) 110 return -1; 111 else if (s1[u] > s2[u]) 112 return 1; 113 } 114 if (s1.length < s2.length) 115 return -1; 116 else if (s1.length > s2.length) 117 return 1; 118 return 0; 119 } 120 inout(TypeInfo)121 override @property inout(TypeInfo) next() inout 122 { 123 return cast(inout)typeid(uint); 124 } 125 } 126 127 unittest 128 { 129 // Original test case from issue 13073 130 uint x = 0x22_DF_FF_FF; 131 uint y = 0xA2_DF_FF_FF; 132 assert(!(x < y && y < x)); 133 uint[] a = [x]; 134 uint[] b = [y]; 135 assert(!(a < b && b < a)); // Original failing case 136 uint[1] a1 = [x]; 137 uint[1] b1 = [y]; 138 assert(!(a1 < b1 && b1 < a1)); // Original failing case 139 } 140 141 // dchar[] 142 143 class TypeInfo_Aw : TypeInfo_Ak 144 { toString()145 override string toString() const { return "dchar[]"; } 146 inout(TypeInfo)147 override @property inout(TypeInfo) next() inout 148 { 149 return cast(inout)typeid(dchar); 150 } 151 } 152