1 /******************************************************************************* 2 3 Utilities for common CTFE operations needed for code generation 4 5 NB: because this module is often used as purely compile-time dependency it 6 used built-in asserts instead of `ocean.core.Test` to reduce amount of 7 cyclic imports. `ocean.meta` modules in general are not supposed to 8 import anything outside of `ocean.meta`. 9 10 Copyright: 11 Copyright (c) 2017 dunnhumby Germany GmbH. All rights reserved. 12 13 License: 14 Boost Software License Version 1.0. See LICENSE_BOOST.txt for details. 15 Alternatively, this file may be distributed under the terms of the Tango 16 3-Clause BSD License (see LICENSE_BSD.txt for details). 17 18 *******************************************************************************/ 19 20 module ocean.meta.codegen.CTFE; 21 22 import ocean.meta.types.Qualifiers; 23 import ocean.text.Ascii : toUpper; 24 25 /******************************************************************************* 26 27 Converts integer to string 28 29 Params: 30 i = integer to convert 31 32 *******************************************************************************/ 33 34 istring toString ( T ) ( T i ) 35 { 36 if (i == 0) 37 return "0"; 38 39 if (i < 0) 40 return "-" ~ toStringImpl(- cast(long) i); 41 42 return toStringImpl(cast(ulong) i); 43 } 44 45 unittest 46 { 47 static assert (toString(0L) == "0"); 48 static assert (toString(42L) == "42"); 49 static assert (toString(-42L) == "-42"); 50 static assert (toString(31L) == "31"); 51 static assert (toString(-31L) == "-31"); 52 static assert (toString(14L) == "14"); 53 static assert (toString(long.max) == "9223372036854775807"); 54 static assert (toString(long.min) == "-9223372036854775808"); 55 static assert (toString(int.min) == "-2147483648"); 56 static assert (toString(int.max) == "2147483647"); 57 static assert (toString(short.min) == "-32768"); 58 static assert (toString(short.max) == "32767"); 59 } 60 61 unittest 62 { 63 assert (toString(14UL) == "14"); 64 static assert (toString(14UL) == "14"); 65 assert (toString(ulong.max) == "18446744073709551615"); 66 static assert (toString(ulong.max) == "18446744073709551615"); 67 } 68 69 unittest 70 { 71 assert (toString(cast(short) 14) == "14"); 72 } 73 74 istring toStringImpl ( ulong i ) 75 { 76 istring digit = "0123456789"; 77 78 if (i == 0) 79 return "0"; 80 81 istring res; 82 83 while (i > 0) 84 { 85 res = digit[i % 10] ~ res; 86 i /= 10; 87 } 88 89 return res; 90 } 91 92 /******************************************************************************* 93 94 Utility to strip the part before the '.' in a string. 95 96 Params: 97 name = string to scan 98 99 *******************************************************************************/ 100 101 public istring stripQualifiedPrefix ( istring name ) 102 { 103 ptrdiff_t idx = name.length - 1; 104 105 while (idx > 0 && name[idx] != '.') 106 --idx; 107 108 if (idx == 0) 109 return name; 110 else 111 return name[idx + 1 .. $]; 112 } 113 114 unittest 115 { 116 assert (stripQualifiedPrefix("aa.bb") == "bb"); 117 static assert (stripQualifiedPrefix("aa.bb") == "bb"); 118 assert (stripQualifiedPrefix("aa.bb.cc") == "cc"); 119 static assert (stripQualifiedPrefix("aa.bb.cc") == "cc"); 120 assert (stripQualifiedPrefix("aabb") == "aabb"); 121 static assert (stripQualifiedPrefix("aabb") == "aabb"); 122 } 123 124 125 /****************************************************************************** 126 127 Converts a snake_case name to a PascalCase. 128 129 This function is designed for use at compile time and is thus not careful 130 about avoiding allocations. 131 132 Params: 133 value = the snake_case value 134 135 Returns: 136 The value in camel case 137 138 ******************************************************************************/ 139 140 string snakeToPascal ( string value ) 141 { 142 string result; 143 bool shouldCapitalize = true; 144 145 foreach ( ch; value ) 146 { 147 if ( ch == '_' ) 148 { 149 shouldCapitalize = true; 150 continue; 151 } 152 153 if ( shouldCapitalize ) 154 { 155 result ~= toUpper([ch]); 156 shouldCapitalize = false; 157 } 158 else 159 { 160 result ~= ch; 161 } 162 } 163 164 return result; 165 } 166 167 /// 168 unittest 169 { 170 assert (snakeToPascal("") == ""); 171 assert (snakeToPascal("a") == "A"); 172 assert (snakeToPascal("Aaaa") == "Aaaa"); 173 assert (snakeToPascal("aaaa_bbbbb") == "AaaaBbbbb"); 174 }