Changeset 160

Show
Ignore:
Timestamp:
03/09/06 08:25:20 (2 years ago)
Author:
Don Clugston
Message:

Many accumulated changes to 'meta'. The most interesting is the one in feqtest, which tests floating point numbers for equality to the number of decimal places given in a string.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/meta/conv.d

    r126 r160  
    66  * Author: Don Clugston. License: Public domain. 
    77  */ 
     8/* 
     9Normally, a function which processes the first part of a string 
     10would return the part which was not consumed (the 'tail'). 
     11This doesn't work very well for D templates, so for such functions, 
     12we supply a seperate metafunction with the suffix 'Consumed' which returns 
     13the  number of characters consumed. (This is the same as the index of the first 
     14character in the string which was not consumed). 
     15This results in some code duplication, but seems to results in a much cleaner design. 
     16*/ 
    817   
    918module meta.conv; 
     
    2029template itoa(long n) 
    2130{ 
    22     static if (n<0) { 
    23         const char [] itoa = "-" ~ .itoa!(-n);  
    24     } else static if (n<10L) { 
     31    static if (n<0) 
     32        const char [] itoa = "-" ~ itoa!(-n);  
     33    else static if (n<10L) 
    2534        const char [] itoa = decimaldigit!(n); 
    26     } else { 
     35    else 
    2736        const char [] itoa = itoa!(n/10L) ~ decimaldigit!(n%10L); 
    28     } 
    2937} 
    3038 
    3139template toHexString(ulong n) 
    3240{ 
    33     static if (n<16L) { 
     41    static if (n<16L) 
    3442        const char [] toHexString = hexdigit!(n); 
    35     } else { 
     43    else 
    3644        const char [] toHexString = toHexString!(n >> 4) ~ hexdigit!(n&0xF); 
    37     } 
    3845} 
    3946 
     
    4148 *  long atoi!(char [] s); 
    4249 */ 
    43 template atoi(char [] s, long sofar=0, int indx=0) 
    44 
    45   static if (s.length==indx) const long atoi=sofar; 
    46   else static if (indx==0 && s[indx]=='-') const long atoi = -.atoi!(s, 0, 1); 
    47   else static if (!isdigit!( (s[indx]) ) ) const long atoi = sofar; 
    48   else const long atoi = .atoi!(s, sofar * 10 + s[indx]-'0', indx+1); 
     50template atoi(char [] s, long result=0, int indx=0) 
     51
     52    static if (s.length==indx) 
     53        const long atoi = result; 
     54    else static if (indx==0 && s[indx]=='-') 
     55        const long atoi = - atoi!(s, 0, 1); 
     56    else static if (!isdigit!( (s[indx]) ) ) 
     57        const long atoi = result; 
     58    else  
     59        const long atoi = atoi!(s, result * 10 + s[indx]-'0', indx+1); 
    4960} 
    5061 
     
    5263 *  the number of characters in s[] which would be 'consumed' by atoi!(). 
    5364 */ 
    54 template countleadingdigits(char [] s, int indx=0) 
    55 
    56     static if (s.length==indx) { 
    57         const int countleadingdigits=indx; 
    58     } else static if (indx==0 && s[indx]=='-')  { 
    59         const int countleadingdigits = countleadingdigits!(s, indx+1); 
    60     } else static if (!isdigit!( (s[indx]) )) { 
    61         const int countleadingdigits=indx; 
    62     } else { 
    63         const int countleadingdigits = countleadingdigits!(s, indx+1); 
    64     } 
    65 
    66  
    67 /* ***************************** 
    68  *  int sigFigs!(char [] s) 
    69  * 
    70  * Returns the number of significant figures in the decimal number s. 
    71  * Leading zeros do not count towards the number of significant figures; 
    72  * eg, sigFigs!(0.000003) == 1. 
    73  *   sigFigs!(0.00000) == 0. 
    74  */ 
    75 template sigFigs(char [] s, int p=0, bool stillzero=true) 
    76 
    77     static if ( s.length ==p ) { 
    78         static if (p>0 && stillzero) { 
    79             const int sigFigs = 1; // the number was zero 
    80         } else { 
    81             const int sigFigs = 0; 
    82         } 
    83     } else static if ( s[p]=='.'|| (p==0 && s[p]=='-') ) { 
    84         const int sigFigs = sigFigs!(s, p+1, stillzero); 
    85     } else static if (s[p]=='0' && stillzero) { 
    86         const int sigFigs = sigFigs!(s, p+1, stillzero); 
    87     } else static if ( isdigit!((s[p])) ) { 
    88         const int sigFigs = 1 + sigFigs!(s, p+1, false); 
    89     } else static if ( s[p]=='e' || s[p]=='E' ) { 
    90         // abort once we reach the exponent 
    91         const int sigFigs=0; 
    92     } else { 
    93         static assert(0); // invalid character in string 
    94     } 
    95 
    96  
    97  
     65template atoiConsumed(char [] s, int indx=0) 
     66
     67    static if(s.length==indx) 
     68        const int atoiConsumed = indx; 
     69    else static if ((indx==0 && s[indx]=='-') || isdigit!( (s[indx]) ) ) 
     70        const int atoiConsumed = atoiConsumed!(s,indx + 1); 
     71    else    // invalid character 
     72        const int atoiConsumed = indx; 
     73
     74 
     75private enum  EFloatParseState { START=0, GOTSIGN, WAITDOT, WAITEXP=3, GOTEXPCHAR, GOTEXPSIGN, EXPDIG }; 
     76 
     77 
     78// Like atoi!(), except that internal underscores are allowable 
     79template parseInt(char [] s, long result=0, EFloatParseState state =0 /* start*/) 
     80
     81    static if (s.length==0)  
     82        const long parseInt = result; 
     83    else static if (state == EFloatParseState.START && s[0]=='-') 
     84        const long parseInt = - parseInt!(s[1..$], 0, GOTSIGN); 
     85    else static if (state == EFloatParseState.WAITDOT && s[0]=='_') 
     86        const long parseInt = parseInt!(s[1..$], result, state); 
     87    else static if (isdigit!( (s[0]) ) )  
     88        const long parseInt = parseInt!(s[1..$], result*10 + s[0]-'0', WAITDOT); 
     89
     90 
     91// Returns the value of the exponent. 
     92// must be of the form "" or  "e-543" or "E+2_453" etc  
     93template parseExponent(char [] s, int result = 0, EFloatParseState state = EFloatParseState.WAITEXP) 
     94
     95    static if (s.length == 0) { 
     96        // an empty string is acceptable 
     97        static if (state == EFloatParseState.WAITEXP || state == EFloatParseState.EXPDIG) 
     98            const int parseExponent = result; 
     99        else { 
     100            pragma(msg, "Error: No exponent found in floating-point literal."); 
     101            static assert(0); 
     102        } 
     103    } else static if (state == EFloatParseState.WAITEXP && (s[0]=='e' || s[0]=='E') ) 
     104        const int parseExponent = parseExponent!(s[1..$], 0, EFloatParseState.GOTEXPCHAR); 
     105    else static if (state == EFloatParseState.GOTEXPCHAR && s[0]=='-') 
     106        const int parseExponent = -parseExponent!(s[1..$], 0, EFloatParseState.GOTEXPSIGN); 
     107    else static if (state == EFloatParseState.GOTEXPCHAR && s[0]=='+') 
     108        const int parseExponent = parseExponent!(s[1..$], 0, EFloatParseState.GOTEXPSIGN); 
     109    else static if (state == EFloatParseState.EXPDIG && s[0]=='_') 
     110        // embedded underscores are allowed after the first digit 
     111        const int parseExponent = parseExponent!(s[1..$], result, state); 
     112    else static if (isdigit!( (s[0]) ) ) 
     113       const int parseExponent = parseExponent!(s[1..$], result*10 + (s[0]-'0'), EFloatParseState.EXPDIG);     
     114    else { 
     115        pragma(msg, "Error: Invalid characters found in floating-point literal."); 
     116        static assert(0); 
     117    } 
     118
     119 
     120// parse a %f-style floating-point number, returning the result as a real. 
     121// A minus sign is allowed as the first character. 
     122// Embedded underscores are allowed any time after the first digit. 
     123template parseMantissa(char [] s, EFloatParseState state = EFloatParseState.START, real result=0.0L) 
     124
     125    static if (s.length==0)  
     126        const real parseMantissa = result; 
     127    else static if (state==EFloatParseState.START && s[0]=='-') 
     128        const real parseMantissa = - parseMantissa!(s[1..$], EFloatParseState.GOTSIGN, 0.0L); 
     129    else static if (state==EFloatParseState.WAITDOT && s[0]=='.') 
     130        const real parseMantissa = result + parseMantissa!(s[1..$], EFloatParseState.WAITEXP, 0.0L); 
     131    else static if (state!=EFloatParseState.START  && state!=EFloatParseState.GOTSIGN && s[0]=='_') 
     132        // allow embedded underscores, but not before the first digit 
     133        const real parseMantissa = parseMantissa!(s[1..$], state, result); 
     134    else static if (isdigit!( (s[0]) )) { 
     135        static if (state == EFloatParseState.WAITEXP) 
     136            // fractional part 
     137            const real parseMantissa = result + (s[0]-'0')/10.0L + parseMantissa!(s[1..$], state, 0.0L) /10.0L; 
     138        else 
     139            const real parseMantissa = parseMantissa!(s[1..$], EFloatParseState.WAITDOT, result*10.0L + (s[0]-'0') ); 
     140    } else static if (state == EFloatParseState.WAITDOT || state == EFloatParseState.WAITEXP) 
     141            const real parseMantissa = result; 
     142    else { 
     143        pragma(msg, "Error: No digits found in floating-point literal."); 
     144        static assert(0); 
     145    } 
     146
     147 
     148template parseMantissaConsumed(char [] s, EFloatParseState state = EFloatParseState.START) 
     149
     150    static if (s.length == 0) 
     151        const int parseMantissaConsumed = 0; 
     152    else static if (state==EFloatParseState.START && s[0]=='-') 
     153        const int parseMantissaConsumed = 1 + parseMantissaConsumed!(s[1..$], EFloatParseState.GOTSIGN); 
     154    else static if (state==EFloatParseState.WAITDOT && s[0]=='.') 
     155        const int parseMantissaConsumed = 1 + parseMantissaConsumed!(s[1..$], EFloatParseState.WAITEXP); 
     156    else static if (state!=EFloatParseState.START  && state!=EFloatParseState.GOTSIGN && s[0]=='_') 
     157        // allow embedded underscores, but not before the first digit 
     158        const int parseMantissaConsumed = 1 + parseMantissaConsumed!(s[1..$], state); 
     159    else static if (isdigit!( (s[0]) )) 
     160        const int parseMantissaConsumed = 1 + parseMantissaConsumed!(s[1..$], 
     161            (state == EFloatParseState.WAITEXP) ? state : EFloatParseState.WAITDOT ); 
     162    else // found first offending character.  
     163        //static assert(state != EFloatParseState.START && state!= EFloatParseState.GOTSIGN); 
     164        const int parseMantissaConsumed = 0; 
     165
     166 
     167 
     168// accepts %f or %e format. 
     169template atof(char [] s) 
     170
     171    const real atof = parseMantissa!(s) * meta.math.pow!(10.0L,  
     172            parseExponent!(s[parseMantissaConsumed!(s)..$])); 
     173
     174 
     175// returns number of decimal places in s. 
     176// s must be a valid floating-point literal 
     177template decimalplaces(char [] s, bool gotDot = false) 
     178
     179    static if (s.length==0) 
     180        const int decimalplaces = 0; 
     181    else static if ( !gotDot && s[0]=='.') 
     182        const int decimalplaces = decimalplaces!(s[1..$], true); 
     183    else static if (s[0]=='_' || !gotDot) { 
     184        const int decimalplaces = decimalplaces!(s[1..$], gotDot); 
     185    } else { 
     186        static if (isdigit!( (s[0]) ) ) 
     187            const int decimalplaces = 1 + decimalplaces!(s[1..$], true); 
     188        else // we've finished 
     189            const int decimalplaces = 0; 
     190    } 
     191
     192 
     193 
     194//------------------------------------------------ 
    98195// Given a number x, where 0<= x <1, 
    99196// returns the first 'maxdigs' digits after the decimal point. 
    100197template afterdec(real x, int maxdigs=real.dig) 
    101198{ 
    102   static if (maxdigs==0 || x==0) const char [] afterdec = ""; 
     199    static if (maxdigs==0 || x==0) const char [] afterdec = ""; 
    103200  else const char [] afterdec = decimaldigit!(cast(int)(x*10)) ~ afterdec!(x*10-cast(int)(x*10), maxdigs-1); 
    104201} 
     
    138235 
    139236version(testmeta) { 
    140  private import meta.strhacks; 
    141  
    142  static assert( streq!(pcvt!(0x1.12345p954L), "0x1.123450p+954") ); 
    143  static assert( streq!(fcvt!(12.345), "12.345") ); 
     237 
     238 
     239    static assert(parseMantissa!("3.34") == 3.34); 
     240    static assert(parseMantissa!("-548_29.317_1abc") == -548_29.317_1); 
     241    static assert( isPositiveZero!(parseMantissa!("0.0"))); 
     242    static assert( isNegativeZero!(parseMantissa!("-0.0"))); 
     243    static assert(parseMantissaConsumed!("-31_4.3252e34") == 10); 
     244    static assert(parseMantissaConsumed!("_23e112") == 0); 
     245 
     246 static assert( pcvt!(0x1.12345p954L) == "0x1.123450p+954" ); 
     247 static assert( fcvt!(12.345) == "12.345" ); 
    144248 
    145249 static assert( atoi!("3580abc")==3580); 
    146250 static assert( atoi!("-0326")==-326); 
    147  static assert( countleadingdigits!("325827wip")==6); 
    148  static assert( countleadingdigits!("abc")==0); 
    149  static assert( sigFigs!("1.2500")==5); 
    150  static assert( sigFigs!("-380.0")==4); 
    151  static assert( sigFigs!("0")==1); 
    152  static assert( sigFigs!("0.0025")==2); 
    153  static assert( sigFigs!("-1.20e49")==3); 
    154 
     251 static assert( atoiConsumed!("325827wip")==6); 
     252 static assert( atoiConsumed!("abc")==0); 
     253
  • trunk/meta/ctype.d

    r93 r160  
     1/* 
     2 * Written by Don Clugston 
     3 * Placed into the Public Domain 
     4 */ 
    15/** 
    26 * Simple ASCII character classification functions. Compile-time equivalents of std.ctype 
     7 * All these functions return false if presented with a non-ASCII character. 
    38 */ 
    49module meta.ctype; 
  • trunk/meta/demangle.d

    r126 r160  
    2020{ 
    2121  static if (str[0] == 'T') { 
    22      const char [] extractQualifiedNameFromAliasParameter = convertToDotName!(str[2..$], onlyWantLastPart); 
     22     const char [] extractQualifiedNameFromAliasParameter =  
     23     extractQualifiedNameFromStatic!(str[2..$], onlyWantLastPart); 
     24     //convertToDotName!(str[2..$], onlyWantLastPart); 
    2325  } else { 
    2426    const char [] extractQualifiedNameFromAliasParameter = extractQualifiedNameFromStatic!(demanglegethead!(str[1..$]), onlyWantLastPart);  
     
    6971      static if (getDotNameTail!(str[2..$])[0]=='F') { 
    7072          // it's a function (not a function pointer) 
    71           const char [] demangleStatic = demangleFunction!( 
     73          static if (getParamListTail!(getDotNameTail!(str[2..$])).length==0) { 
     74            const char [] demangleStatic = demangleFunction!(getDotNameTail!(str[2..$]),  
     75                    convertToDotName!(str[2..$])   ); 
     76          } else { 
     77          const char [] demangleStatic = " <<" ~ getParamListTail!(str[2..$]) ~ ">> " ~ demangleFunction!( 
    7278          getDotNameTail!(str[2..$]),  
    7379          convertToDotName!(str[2..$]) 
    7480          ); 
    75            
    76           /* 
    77           demangleReturnValue!(str[1..(str.length)]) ~ " name (" 
    78         ~ demangleParamList!(str[1..(str.length)]) ~ ")"; 
     81          } 
     82/*           
     83          const char [] demangleStatic = demangleReturnValue!(str[2..$]) ~ getDotNameTail!(str[2..$]) 
     84        ~ demangleParamList!(str[1..$]) ~ ")"; 
    7985        */ 
    8086      } else { 
     
    162168    static if(str.length == 0) { 
    163169        const char [] convertToDotName=""; 
    164     } else static if (isdigit!((str[0]))) { 
     170    } else static if (isdigit!((str[0])) || (str.length>=4 && str[0..4]=="main") ) { 
    165171       static if (onlyWantLastPart && demanglegettail!(str).length > 0) { 
    166172         static if (isdigit!((demanglegettail!(str)[0]))) { 
     
    175181            ~ .convertToDotName!(demanglegettail!(str), onlyWantLastPart, "."); 
    176182       } 
    177   } 
    178   else const char [] convertToDotName=""; // ignore the tail 
     183  } else static if (str[0]=='F') { 
     184     const char [] convertToDotName = convertToDotName!(getParamListTail!(str), onlyWantLastPart, "()."); 
     185  } else  
     186    const char [] convertToDotName="--TAIL["~ str ~ "]"; // ignore the tail 
    179187} 
    180188 
     
    184192        const char [] getDotNameTail=""; 
    185193    } else static if (isdigit!((str[0]))) { 
    186         const char [] getDotNameTail = .getDotNameTail!(demanglegettail!(str)); 
    187   } else const char [] getDotNameTail = str; 
     194        const char [] getDotNameTail = getDotNameTail!(demanglegettail!(str)); 
     195  } else static if (str.length>4 && str[0..4]=="main") { 
     196        const char [] getDotNameTail = getDotNameTail!(str[4..$]); 
     197  } else { 
     198    const char [] getDotNameTail = str; 
     199  } 
    188200} 
    189201 
    190202template demanglegethead(char [] str) 
    191203{ 
    192   static if (str.length<=10 || !isdigit!( (str[1]) ) ) { 
     204  static if (str.length>4 && str[0..4]=="main") { 
     205     const char [] demanglegethead = "main"; 
     206  } else static if (str.length<=10 || !isdigit!( (str[1]) ) ) { 
    193207     const char [] demanglegethead = str[1..(str[0]-'0' + 1)]; 
    194208  } else static if (str.length<=100 || !isdigit!( (str[2]) )) { 
     
    202216template demanglegettail(char [] str) 
    203217{ 
    204    static if (str.length<=10 || !isdigit!( (str[1]) ) ) { 
     218  static if (str.length>4 && str[0..4]=="main") { 
     219     const char [] demanglegettail = str[4..$]; 
     220  } else static if (str.length<=10 || !isdigit!( (str[1]) ) ) { 
    205221     const char [] demanglegettail = str[(str[0]-'0'+1) .. $]; 
    206222  } else static if (str.length<=100 || !isdigit!( (str[2]) )) { 
  • trunk/meta/demo/calcpi.d

    r115 r160  
    77import meta.math; 
    88import meta.conv; 
    9  
    10 import std.math; 
    119 
    1210/** real evaluateSeries!(real x, real metafunction!(real y, int n) term) 
     
    2624     const real evaluateSeries = sumsofar; 
    2725  } else { 
    28      const real evaluateSeries = .evaluateSeries!(x, term, n+1, sumsofar + term!(x, n)); 
     26     const real evaluateSeries = evaluateSeries!(x, term, n+1, sumsofar + term!(x, n)); 
    2927  } 
    3028} 
  • trunk/meta/demo/tabledemo.d

    r126 r160  
    33// Create a constant array of long or ulong-sized items. Needs to be cast back to 
    44// long[] or ulong[]. 
    5 template generateArray(alias entry, int n) 
     5template generateArrayAsChar(alias entry, int n) 
    66{ 
    77  static if ( entry!(0).sizeof == dchar.sizeof) { 
    88      // int or uint sized items 
    99      static if (n==0) { 
    10         const dchar [] generateArray = ""d  ~ cast(dchar)entry!(n); 
     10        const dchar [] generateArrayAsChar = ""d  ~ cast(dchar)entry!(n); 
    1111      } else { 
    12         const dchar[] generateArray = generateArray!(entry, n-1) ~ cast(dchar)entry!(n); 
     12        const dchar[] generateArrayAsChar = generateArrayAsChar!(entry, n-1) ~ cast(dchar)entry!(n); 
    1313      } 
    1414  } else static if ( entry!(0).sizeof == 2*dchar.sizeof) { 
    1515      // long or ulong sized items 
    1616      static if (n==0) { 
    17         const dchar [] generateArray = ""d   
     17        const dchar [] generateArrayAsChar = ""d   
    1818                ~ cast(dchar)entry!(n) ~ cast(dchar)(entry!(n)>>>32); 
    1919      } else { 
    20         const dchar[] generateArray = generateArray!(entry, n-1) 
     20        const dchar[] generateArrayAsChar = generateArrayAsChar!(entry, n-1) 
    2121            ~ cast(dchar)entry!(n)  ~ cast(dchar)(entry!(n)>>32); 
    2222      } 
     
    2424} 
    2525 
     26template generateArray(alias entry, int n) 
     27{ 
     28  const typeof(entry!(0)) [] generateArray = cast(typeof(entry!(0)) [])generateArrayAsChar!(entry, n); 
     29} 
     30 
     31// The ubiquitous factorial function 
     32// 
    2633// Returns correct value for n=0 (factorial!(0)=1). 
    2734template factorial(int n) 
    2835{ 
    29   static if (n<2) const ulong factorial = 1; 
    30   else const ulong factorial = n * .factorial!(n-1); 
     36  static if (n<2) const uint factorial = 1; 
     37  else const uint factorial = n * factorial!(n-1); 
    3138} 
    3239 
     40// Make an array of all the factorials from 0 to 13 (14!> ulong.max) 
     41const smallfactorials = generateArray!(factorial, 13); 
    3342 
     43 
     44/+ 
    3445// Make an array of all the factorials from 0 to 20 (21!> ulong.max) 
    3546const ulong [] smallfactorials; 
    36  
    3747static this() 
    3848{ 
    39     smallfactorials = cast(ulong []) generateArray!(factorial, 20); 
     49    smallfactorials = cast(uint []) generateArrayAsChar!(factorial, 20); 
    4050} 
    41  
     51+/ 
    4252import std.stdio; 
    4353 
    44 int main() 
     54void main() 
    4555{ 
    4656  for (int i=0; i<smallfactorials.length; ++i) { 
    4757     writefln(i, "  ", smallfactorials[i]); 
    4858  } 
    49  return 0; 
    5059} 
    51  
    52 /+ 
    53 // ---------- array literals version ----------- 
    54  
    55 template generateArray(alias entry, int n) 
    56 { 
    57     static if (n==0) { 
    58         const typeof(entry!(0)) [] generateArray = [ entry!(n) ]; 
    59     } else { 
    60         const typeof(entry!(0)) [] generateArray = generateArray!(entry, n-1) ~ [ entry!(n) ]; 
    61     } 
    62 } 
    63  
    64 const smallfactorials = generateArray!(factorial, 20); 
    65 +/ 
  • trunk/meta/math.d

    r114 r160  
    1313{ 
    1414  const bool isnan = (x!<>=0); 
     15} 
     16 
     17template isPositiveZero(real x) 
     18{ 
     19    static if (x==0 && 1.0L/x > 0)  
     20        const bool isPositiveZero = true; 
     21    else  
     22        const bool isPositiveZero = false; 
     23} 
     24 
     25template isNegativeZero(real x) 
     26{ 
     27    static if (x==0 && 1.0L/x < 0)  
     28        const bool isNegativeZero = true; 
     29    else  
     30        const bool isNegativeZero = false; 
     31} 
     32 
     33version(testmeta) { 
     34 
     35static assert( isPositiveZero!(0.0L)); 
     36static assert( !isPositiveZero!(-0.0L)); 
     37static assert( !isPositiveZero!(real.nan)); 
     38static assert( isNegativeZero!(-0.0L)); 
     39static assert( !isNegativeZero!(0.0L)); 
    1540} 
    1641 
  • trunk/meta/nameof.d

    r126 r160  
    66// with a method that it does not use the identifier in any way. 
    77 
    8 module meta.qualifiedname
     8module meta.nameof
    99private import meta.demangle; 
    1010 
     
    1818    } 
    1919     
    20     // You can't .mangleof a type, only of an rvalue. But, we can 
    21     // put the type as a function parameter. 
     20    // If you take the .mangleof an alias parameter, you are only 
     21    // told that it is an alias. 
     22    // So, we put the type as a function parameter. 
    2223    template outer(alias B) 
    2324    { 
     
    2829// If the identifier is "MyIdentifier" and this module is "QualModule" 
    2930// The return value will be: 
    30 //  "PPF"   -- because it's a pointer to a pointer to a function 
     31//  "PF"   -- because it's a pointer to a pointer to a function 
    3132//   "C"     -- because the first parameter is a class 
    3233//    "10QualModule"  -- the name of this module 
     
    5152 
    5253    // Get the number of chars at the start relating to the pointer 
    53     const int pointerstartlength = "PPFC".length + modulemanglelength + "__T5innerT".length; 
     54    const int pointerstartlength = "PFC".length + modulemanglelength + "__T5innerT".length; 
    5455    // And the number of chars at the end 
    5556    const int pointerendlength = "Z5innerZv".length; 
     57} 
     58 
     59template rawmanglednameof(alias A) 
     60{ 
     61  const char [] rawmanglednameof  = 
     62  typeof(outer!(A)).mangleof; 
    5663} 
    5764 
     
    6370{ 
    6471  const char [] manglednameof  = 
    65   typeof(&outer!(A)).mangleof[ pointerstartlength + 1 .. $ - pointerendlength]; 
     72  typeof(outer!(A)).mangleof[ pointerstartlength + 1 .. $ - pointerendlength]; 
    6673} 
    6774 
     
    7178// Returns the unqualified name, as a single text string. 
    7279// eg. "myfunc" 
    73 template basicnameof(alias A) 
     80template symbolnameof(alias A) 
    7481{ 
    75   const char [] basicnameof = extractQualifiedNameFromAliasParameter!(manglednameof!(A), true); 
     82  const char [] symbolnameof = extractQualifiedNameFromAliasParameter!(manglednameof!(A), true); 
    7683} 
    7784 
  • trunk/meta/qualtest.d

    r126 r160  
    1 import meta.qualifiedname; 
     1class HaveFun {} 
     2 
     3import meta.nameof; 
    24 
    35 
     
    57{ 
    68  const char [] describe = 
    7                  \n "Mangled  : " ~ manglednameof!(A) ~ 
    8                   \n "Basic    : " ~ basicnameof!(A)  
    9                 ~ \n "Qualified: " ~ qualifiednameof!(A)  
    10                 ~ \n "Pretty   : " ~ prettynameof!(A); 
     9                 \n "Mangled  : " ~ manglednameof!(A) 
     10               ~   \n "Symbol   : " ~ symbolnameof!(A)  
     11;//                ~ \n "Qualified: " ~ qualifiednameof!(A) 
     12//                ~ \n "Pretty   : " ~ prettynameof!(A); 
    1113} 
    1214 
     
    100102} 
    101103 
    102 pragma(msg, "\n-------\n  Local symbols are not yet supported, but there is hope...\n-------"); 
    103104 
    104 void main() 
     105import std.demangle; 
     106import std.stdio; 
     107 
     108void fmain() //(int a, int b) 
    105109{ 
     110 
    106111  class LocalClass { 
     112    class InnerClass {} 
    107113    void LocalFunc() {} 
    108114  } 
    109115  pragma(msg, describe!(LocalClass.LocalFunc)); 
    110      
     116   
     117   
     118 
     119  writefln(LocalClass.mangleof); 
     120  writefln(LocalClass.InnerClass.mangleof); 
     121 
     122pragma(msg, "\n-------\n  Local symbols are not yet supported, but there is hope...\n-------"); 
     123 
     124  mixin ClassTemplate!(int, uint) localMixin; 
     125  pragma(msg, describe!(localMixin)); 
    111126 
    112127  int LocalVar; 
    113128  mixin getname!(LocalVar); 
    114129  pragma(msg, describe!(getname)); 
     130//  writefln(getname.mangleof); 
    115131   
    116132} 
     133 
     134void main() 
     135{ 
     136fmain(); 
     137 // fmain(3, 4); 
     138} 
  • trunk/meta/strhacks.d

    r115 r160  
    1 /** Workarounds required for DMD 0.143 
     1/** Workarounds required for DMD 0.141 - 0.144. 
    22 * 
    33 * Most of these are only required when they are used as a template value parameter. 
    44 */ 
     5  
    56module meta.strhacks; 
     7version(none) { 
    68 
    7 // return true if str1 == str2/ 
    8 template streq(char [] str1, char[] str2) 
    9 { 
    10   static if (str1.length!=str2.length) const bool streq=false; 
    11   else static if (str1[0]!=str2[0]) const bool streq=false; 
    12   else static if (str1.length==1) const bool streq=true; 
    13   else const bool streq = .streq!(str1[1..(str1.length)], str2[1..(str2.length)]); 
    14 } 
    15  
    16 /// converts a single char to a char[] 
    17 template makechar(int c) 
    18 { 
    19   const char [] makechar=x"000102030405060708090a0b0c0d0e0f 
    20                            101112131415161718191a1b1c1d1e1f 
    21                            202122232425262728292a1b2c2d2e2f 
    22                            303132333435363738393a3b3c3d3e3f 
    23                            404142434445464748494a4b4c4d4e4f 
    24                            505152535455565758595a5b5c5d5e5f 
    25                            606162636465666768696a6b6c6d6e6f 
    26                            707172737475767778797a7b7c7d7e7f 
    27                            808182838485868788898a8b8c8d8e8f 
    28                            909192939495969798999a9b9c9d9e9f 
    29                            a0a1a2a3a4a5a6a7a8a9aaabacadaeaf 
    30                            b0b1b2b3b4b5b6b7b8b9babbbcbdbebf 
    31                            c0c1c2c3c4c5c6c7c8c9cacbcccdcecf 
    32                            d0d1d2d3d4d5d6d7d8d9dadbdcdddedf 
    33                            e0e1e2e3e4e5e6e7e8e9eaebecedeeef 
    34                            f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"[c..c+1]; 
    35 } 
    36  
    37 version(testmeta) { 
    38  static assert( streq!("abc", "abc")); 
    39  static assert(!streq!("abc", "axc") ); 
    40  static assert(!streq!("abc", "abcd") ); 
    41 // static assert(streq!("abcdef", "abc" ~ "def")); // this crashes DMD 0.142 
    42  static assert(streq!("abcdef", concat!("abc", "def"))); 
    43 } 
    449 
    4510//----------------------------------------------------------------- 
     
    6025 
    6126//----------------------------------------------------------------- 
    62 //   Workarounds for DMD 0.141, almost work in DMD 0.143 (need to add parentheses) 
     27//   Workarounds for DMD 0.141, fixed in DMD 0.144 
    6328 
    6429///  = str[from..to] 
     
    8550  const char getcharat = str[n]; 
    8651} 
     52//----------------------------------------------------------------- 
     53//   Workarounds fixed in DMD 0.145 
    8754 
     55// return true if str1 == str2 
     56template streq(char [] str1, char[] str2) 
     57{ 
     58  static if (str1.length!=str2.length) const bool streq=false; 
     59  else static if (str1[0]!=str2[0]) const bool streq=false; 
     60  else static if (str1.length==1) const bool streq=true; 
     61  else const bool streq = .streq!(str1[1..(str1.length)], str2[1..(str2.length)]); 
     62} 
     63 
     64 
     65version(testmeta) { 
     66 static assert( streq!("abc", "abc")); 
     67 static assert(!streq!("abc", "axc") ); 
     68 static assert(!streq!("abc", "abcd") ); 
     69// static assert(streq!("abcdef", "abc" ~ "def")); // this crashes DMD 0.142 
     70 static assert(streq!("abcdef", concat!("abc", "def"))); 
     71} 
     72 
     73/// converts a single char to a char[] 
     74template makechar(int c) 
     75{ 
     76  const char [] makechar=x"000102030405060708090a0b0c0d0e0f 
     77                           101112131415161718191a1b1c1d1e1f 
     78                           202122232425262728292a1b2c2d2e2f 
     79                           303132333435363738393a3b3c3d3e3f 
     80                           404142434445464748494a4b4c4d4e4f 
     81                           505152535455565758595a5b5c5d5e5f 
     82                           606162636465666768696a6b6c6d6e6f 
     83                           707172737475767778797a7b7c7d7e7f 
     84                           808182838485868788898a8b8c8d8e8f 
     85                           909192939495969798999a9b9c9d9e9f 
     86                           a0a1a2a3a4a5a6a7a8a9aaabacadaeaf 
     87                           b0b1b2b3b4b5b6b7b8b9babbbcbdbebf 
     88                           c0c1c2c3c4c5c6c7c8c9cacbcccdcecf 
     89                           d0d1d2d3d4d5d6d7d8d9dadbdcdddedf 
     90                           e0e1e2e3e4e5e6e7e8e9eaebecedeeef 
     91                           f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"[c..c+1]; 
     92} 
     93 
     94} 
  • trunk/meta/string.d

    r115 r160  
    99  static if (str.length==0) const char[] chomp=str; 
    1010  else static if (str[str.length - 1]==delimiter)  
    11      const char [] chomp = .chomp!( str[0..(str.length-1)], delimiter); 
     11     const char [] chomp = chomp!( str[0..$-1], delimiter); 
    1212  else const char [] chomp = str; 
    1313} 
     
    2222  static if (str.length==n) const int find = -1; 
    2323  else static if( c==str[n]) const int find = n; 
    24   else const int find = .find!(str, c, n + 1); 
     24  else const int find = find!(str, c, n + 1); 
    2525} 
    2626 
     
    3434  static if (str.length==n) const int rfind = -1; 
    3535  else static if( c==str[str.length - n - 1]) const int rfind = str.length - n - 1; 
    36   else const int rfind = .rfind!(str, c, n + 1); 
     36  else const int rfind = rfind!(str, c, n + 1); 
    3737} 
    3838 
     
    4444   static if (n==0) const char [] repeat=""; 
    4545   else static if (n==1) const char [] repeat = str; 
    46    else const char [] repeat = str ~ .repeat!(str, n-1); 
     46   else const char [] repeat = str ~ repeat!(str, n-1); 
    4747} 
    4848 
     
    5353 static assert( -1 == rfind!("not in here either", 'z')); 
    5454 static assert( 4 == rfind!("but this is ok", 't')); 
    55  static assert(streq!(repeat!("abc", 4), "abcabcabcabc")); 
     55 static assert(repeat!("abc", 4) == "abcabcabcabc"); 
    5656}