Skip to content

Commit

Permalink
Implemented hasSameMembers
Browse files Browse the repository at this point in the history
  • Loading branch information
ColdenCullen committed Aug 2, 2014
1 parent 079b520 commit 1c61905
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 30 deletions.
5 changes: 3 additions & 2 deletions source/quack/extends.d
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import quack;
* Checks if Child extends Parent in any of the supported ways.
*
* Params:
* Child = The base class to test.
* Child = The base class to test.
* Parent = The parent class to test.
*
* Returns:
Expand All @@ -18,7 +18,8 @@ template extends( Child, Parent )
{
enum extends =
is( Child : Parent ) ||
isAliasThis!( Child, Parent );
isAliasThis!( Child, Parent ) ||
hasSameMembers!( Child, Parent );
}
///
unittest
Expand Down
77 changes: 77 additions & 0 deletions source/quack/membertest.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/**
*
*/
module quack.membertest;
import quack.extends;

import std.algorithm: among;

/**
* Checks if Child extends Parent by having a matching set of members.
*
* Params:
* Child = The base class to test.
* Parent = The parent class to test.
*
* Returns:
* Whether Child has all the members of Parent.
*/
template hasSameMembers( Base, Parent )
{
static if( isExtendable!( Base, Parent ) )
{
enum hasSameMembers = {
// If there are no members to check, return false.
static if( [__traits( allMembers, Parent )].length == 0 )
{
return false;
}
else
{
foreach( member; __traits( allMembers, Parent ) )
{
// Ignore some members.
static if( !member.among( "this" ) )
{
// If Base has the member, check the type.
static if( __traits( hasMember, Base, member ) )
{
static if( !is(
typeof( __traits( getMember, Parent, member ) ) ==
typeof( __traits( getMember, Base, member ) )
) )
{
return false;
}
}
else
{
return false;
}
}
}

return true;
}
} ();
}
else
{
enum hasSameMembers = false;
}
}
///
unittest
{
struct S1
{
@property int x() { return 42; }
}

struct S2
{
@property int x() { return 42; }
}

assert( hasSameMembers!( S1, S2 ) );
}
32 changes: 4 additions & 28 deletions source/quack/mixins.d
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* defines all the same members of a template mixin.
*/
module quack.mixins;
import quack.extends;
import quack.extends, quack.membertest;

/**
*
Expand All @@ -12,37 +12,13 @@ template hasTemplateMixin( Base, alias mix )
{
static if( isExtendable!Base )
{
//TODO: Make sure `mixin mix!();` compiles.
private struct MixImpl
{
/*static if( __traits( compiles, mixin mix ) )
{*/
mixin mix!();
//}
mixin mix!();
}

enum hasTemplateMixin = {
bool isEqual = false;

foreach( member; __traits( allMembers, MixImpl ) )
{
static if( __traits( hasMember, Base, member ) )
{
static if( is(
typeof( __traits( getMember, MixImpl, member ) ) ==
typeof( __traits( getMember, Base, member ) )
) )
{
isEqual = true;
}
}
else
{
return false;
}
}

return isEqual;
} ();
enum hasTemplateMixin = hasSameMembers!( Base, MixImpl );
}
else
{
Expand Down
1 change: 1 addition & 0 deletions source/quack/package.d
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ public:
import quack.extends;
import quack.aliasthis;
import quack.mixins;
import quack.membertest;

0 comments on commit 1c61905

Please sign in to comment.