Differences From Artifact [cc1b586b87325960]:
- File        
tricks/tricks.d
- 2010-11-23 09:36:27 - part of checkin [b97bd4f713] on branch trunk - automatic AST to table encoder (user: kinaba) [annotate]
 
To Artifact [00969146488cc3dc]:
- File        
tricks/tricks.d
- 2010-11-24 17:44:58 - part of checkin [b993a8ad16] on branch trunk - auto memo and re-run feature of non @value/@macro layers re-re-re-implemented. (user: kinaba) [annotate]
 
   95          // shiyo- desu. Don't use in this way.                                        95          // shiyo- desu. Don't use in this way.
   96          //   Tamp tries to call new Tomp(real) (because it only sees Tomp's memb      96          //   Tamp tries to call new Tomp(real) (because it only sees Tomp's memb
   97          //   but it fails because Tomp takes (int,string,real).                       97          //   but it fails because Tomp takes (int,string,real).
   98          assert( !__traits(compiles, {                                                 98          assert( !__traits(compiles, {
   99                  class Tamp : Tomp { mixin SimpleConstructor; }                        99                  class Tamp : Tomp { mixin SimpleConstructor; }
  100          }) );                                                                        100          }) );
  101  }                                                                                    101  }
                                                                                        >   102  
                                                                                        >   103  hash_t structuralHash(T)(T x)
                                                                                        >   104  {
                                                                                        >   105          alias SC_Unqual!(T) UCT;
                                                                                        >   106  
                                                                                        >   107          static if(is(UCT == class))
                                                                                        >   108                  return (cast(UCT)x).toHash();
                                                                                        >   109          else
                                                                                        >   110          static if(SC_HasGoodHash!(UCT))
                                                                                        >   111                  { return typeid(UCT).getHash(&x); }
                                                                                        >   112          else
                                                                                        >   113          static if(is(UCT T == T[]))
                                                                                        >   114                  { hash_t h; foreach(e; x) h+=structuralHash(e); return h; }
                                                                                        >   115          else
                                                                                        >   116          static if(is(UCT == struct))
                                                                                        >   117                  static if(__traits(compiles, std.bigint.BigInt))
                                                                                        >   118                          static if(is(UCT == std.bigint.BigInt))
                                                                                        >   119                                  return cast(hash_t) x.toInt();
                                                                                        >   120                          else
                                                                                        >   121                                  static assert(false, "should not use struct.toHa
                                                                                        >   122                  else
                                                                                        >   123                          static assert(false, "should not use struct.toHash");
                                                                                        >   124          else
                                                                                        >   125                  static assert(false, "nonhashable datatype "~UCT.stringof);
                                                                                        >   126  }
                                                                                        >   127  
                                                                                        >   128  alias std.traits.Unqual SC_Unqual;
                                                                                        >   129  
                                                                                        >   130  template SC_HasGoodHash(T)
                                                                                        >   131  {
                                                                                        >   132          enum SC_HasGoodHash =
                                                                                        >   133                  is(T : bool) || isNumeric!(T) || isSomeString!(T) || isSomeChar!
                                                                                        >   134  }
  102                                                                                       135  
  103  /// Mixing-in the MOST-DERIVED-member-wise comparator for a class                    136  /// Mixing-in the MOST-DERIVED-member-wise comparator for a class
                                                                                        >   137  /// BE SURE THAT THIS IS CONSISTENT WITH opCmp and opEquals
  104                                                                                       138  
  105  template SimpleToHash()                                                              139  template SimpleToHash()
  106  {                                                                                    140  {
  107          override hash_t toHash() const /// member-by-member hash                     141          override hash_t toHash() const /// member-by-member hash
  108          {                                                                            142          {
  109                  hash_t h = 0;                                                        143                  hash_t h = 0;
  110                  foreach(mem; this.tupleof)                                           144                  foreach(mem; this.tupleof)
  111                          h += typeid(mem).getHash(&mem);                          |   145                          h += structuralHash(mem);
  112                  return h;                                                            146                  return h;
  113          }                                                                            147          }
  114  }                                                                                    148  }
                                                                                        >   149  
                                                                                        >   150  /// Mixing-in the MOST-DERIVED-member-wise comparator for a class
                                                                                        >   151  
                                                                                        >   152  template SimpleCompareWithoutToHash()
                                                                                        >   153  {
                                                                                        >   154          override bool opEquals(Object rhs) const /// member-by-member equality
                                                                                        >   155          {
                                                                                        >   156                  return opCmp(rhs) == 0;
                                                                                        >   157          }
                                                                                        >   158  
                                                                                        >   159          override int opCmp(Object rhs_) const /// member-by-member compare
                                                                                        >   160          {
                                                                                        >   161                  if( rhs_ is null )
                                                                                        >   162                          return -1;
                                                                                        >   163                  if( auto rhs = cast(typeof(this))rhs_ )
                                                                                        >   164                  {
                                                                                        >   165                          foreach(i,_; this.tupleof)
                                                                                        >   166                          {
                                                                                        >   167                                  static if(is(typeof(_) == struct))
                                                                                        >   168                                          auto c = (cast(SC_Unqual!(typeof(_)))thi
                                                                                        >   169                                  else
                                                                                        >   170                                          auto c = typeid(_).compare(&this.tupleof
                                                                                        >   171                                  if(c)
                                                                                        >   172                                          return c;
                                                                                        >   173                          }
                                                                                        >   174                          return 0;
                                                                                        >   175                  }
                                                                                        >   176                  return typeid(this).opCmp(typeid(rhs_));
                                                                                        >   177          }
                                                                                        >   178  }
  115                                                                                       179  
  116  /// Mixing-in the MOST-DERIVED-member-wise comparator for a class                    180  /// Mixing-in the MOST-DERIVED-member-wise comparator for a class
  117                                                                                       181  
  118  /*mixin*/                                                                            182  /*mixin*/
  119  template SimpleCompare()                                                             183  template SimpleCompare()
  120  {                                                                                    184  {
  121          override bool opEquals(Object rhs_) const /// member-by-member equality  <
  122          {                                                                        <
  123                  if( auto rhs = cast(typeof(this))rhs_ )                          <
  124                  {                                                                <
  125                          foreach(i,_; this.tupleof)                               <
  126                                  if( this.tupleof[i] != (cast(const)rhs).tupleof[ <
  127                                          return false;                            <
  128                          return true;                                             <
  129                  }                                                                <
  130                  assert(false, sprintf!"Cannot compare %s with %s"(typeid(this),  <
  131          }                                                                        <
  132                                                                                   <
  133          mixin SimpleToHash;                                                          185          mixin SimpleToHash;
  134                                                                                   <
  135          override int opCmp(Object rhs_) const /// member-by-member compare       <
  136          {                                                                        <
  137                  if( auto rhs = cast(typeof(this))rhs_ )                          <
  138                  {                                                                <
  139                          foreach(i,_; this.tupleof)                               <
  140                                  if( this.tupleof[i] != (cast(const)rhs).tupleof[ <
  141                                          auto a = (cast(SC_Unqual!(typeof(this))) <
  142                                          auto b =  rhs.tupleof[i];                <
  143                                          return a < b ? -1 : +1;                  <
  144                                  }                                                <
  145  // not work well for structures???????                                           <
  146  //                              if(auto c = typeid(_).compare(&this.tupleof[i],& <
  147  //                                      return c;                                <
  148                          return 0;                                                <
  149                  }                                                                <
  150                  assert(false, sprintf!"Cannot compare %s with %s"(typeid(this),  <
  151          }                                                                        <
                                                                                        >   186          mixin SimpleCompareWithoutToHash;
  152  }                                                                                    187  }
  153                                                                                       188  
  154  alias std.traits.Unqual SC_Unqual;                                               <
  155                                                                                   <
  156  unittest                                                                             189  unittest
  157  {                                                                                    190  {
  158          class Temp                                                                   191          class Temp
  159          {                                                                            192          {
  160                  int x;                                                               193                  int x;
  161                  string y;                                                            194                  string y;
  162                  mixin SimpleConstructor;                                             195                  mixin SimpleConstructor;
................................................................................................................................................................................
  173          class TempDummy                                                              206          class TempDummy
  174          {                                                                            207          {
  175                  int x;                                                               208                  int x;
  176                  string y;                                                            209                  string y;
  177                  mixin SimpleConstructor;                                             210                  mixin SimpleConstructor;
  178                  mixin SimpleCompare;                                                 211                  mixin SimpleCompare;
  179          }                                                                            212          }
  180          assert_throw!AssertError( new Temp(1,"foo") == new TempDummy(1,"foo") ); |   213          assert_ne( new Temp(1,"foo"), new TempDummy(1,"foo") );
  181          assert_throw!AssertError( new Temp(1,"foo") <= new TempDummy(1,"foo") ); |   214          assert_nothrow( new Temp(1,"foo") <= new TempDummy(1,"foo") );
  182  }                                                                                    215  }
  183                                                                                       216  
  184  /// Mixing-in a simple toString method                                               217  /// Mixing-in a simple toString method
  185                                                                                       218  
  186  /*mixin*/                                                                            219  /*mixin*/
  187  template SimpleToString()                                                            220  template SimpleToString()
  188  {                                                                                    221  {
................................................................................................................................................................................
  222  template SimpleClass()                                                               255  template SimpleClass()
  223  {                                                                                    256  {
  224          mixin SimpleConstructor;                                                     257          mixin SimpleConstructor;
  225          mixin SimpleCompare;                                                         258          mixin SimpleCompare;
  226          mixin SimpleToString;                                                        259          mixin SimpleToString;
  227  }                                                                                    260  }
  228                                                                                       261  
  229  /// Will be used for dynamic overload resolution pattern                         |   262  /// Utility
  230                                                                                       263  
  231  template firstParam(T)                                                               264  template firstParam(T)
  232  {                                                                                    265  {
  233          alias ParameterTypeTuple!(T)[0] firstParam;                                  266          alias ParameterTypeTuple!(T)[0] firstParam;
  234  }                                                                                    267  }