Note: This website is archived. For up-to-date information about D projects and development, please visit wiki.dlang.org.

Changeset 1964

Show
Ignore:
Timestamp:
09/07/10 23:05:25 (14 years ago)
Author:
dsimcha
Message:

Bug 4834: Implicit sharing via delegates in std.concurrency

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/docsrc/changelog.dd

    r1961 r1964  
    77 
    88    $(WHATSNEW 
    99    $(LI std.algorithm:  reduce now works with non-range-based iteration, such as opApply.) 
    1010    $(LI std.numeric:  Added FFT.) 
    1111    $(LI std.process: Added environment, an AA-like interface for environment variables.) 
    1212    $(LI std.range:  Iota, Stride, Transversal, FrontTransveral now support slicing where possible.) 
    1313    $(LI std.range:  Added Lockstep, hasLvalueElements.) 
    1414    $(LI std.range:  Added virtual function-based wrappers (InputRangeObject, OutputRangeObject) for when a binary interface to a range is required.) 
    1515    $(LI std.typecons:  Added convenience functions for Rebindable.) 
    1616    $(L1 std.traits:  Added isAssignable, isIterable, ForeachType, isSafe, isUnsafe, EnumMembers.) 
     17    $(L1 std.traits:  hasLocalAliasing, hasLocalObjects and hasLocalRawAliasing are now hasUnsharedAliasing, hasUnsharedObjects and hasUnsharedRawAliasing.  Aliases to the old names are included for now for backwards compatibility.) 
    1718    $(LI std.typetuple:  Added anySatisfy.) 
    1819    $(LI $(LINK2 phobos/std_stopwatch.html,std.swopwatch):  Added StopWatch, Ticks, systime, apptime, comparingBenchmark, measureTime.) 
    1920    ) 
    2021    $(BUGSFIXED 
    2122    $(LI Unlisted Bug:  std.math.pow doesn't work on immutable numbers.) 
    2223    $(LI Unlisted Bug:  std.math.pow floating point overload expects both arguments to be exact same type.) 
    2324    $(LI Unlisted Bug:  std.path.join("", "foo") returns "/foo" instead of "foo" on Posix.) 
    2425    $(LI Unlisted Bug:  std.range.iota() random access primitives inconsistent after popFront on floating point version) 
    2526    $(LI Several unlisted bugs in std.range.chain) 
    2627    $(LI $(BUGZILLA 2903): Splitter should be bi-dir if the input range is bi-dir.) 
     
    4748    $(LI $(BUGZILLA 4404): std.range.Transversal assumes lvalue elements.) 
    4849    $(LI $(BUGZILLA 4455): Taking the sqrt of an integer shouldn't require an explicit cast.) 
    4950    $(LI $(BUGZILLA 4464): std.range.take does not always return Take!R.) 
    5051    $(LI $(BUGZILLA 4518): to!string(enum w/invalid value) produces a somewhat unhelpful error) 
    5152    $(LI $(BUGZILLA 4603): array(iota(1, 0)) error.) 
    5253    $(LI $(BUGZILLA 4643): Shared values are unwritable.) 
    5354    $(LI $(BUGZILLA 4700): to!float("0") fails) 
    5455    $(LI $(BUGZILLA 4748): Shadowing declaration error in std.string.tolower) 
    5556    $(LI $(BUGZILLA 4789): std.algorithm.sort bug) 
    5657    $(LI $(BUGZILLA 4810): dotProduct problem with ints) 
     58    $(LI $(BUGZILLA 4834): Implicit sharing via delegates in std.concurrency) 
    5759    ) 
    5860) 
    5961 
    6062 
    6163<div id=version> 
    6264$(UL 
    6365    $(NEW 049) 
    6466    $(NEW 048) 
    6567    $(NEW 047) 
    6668    $(NEW 046) 
  • trunk/phobos/std/traits.d

    r1960 r1964  
    10751075struct S4 { int a; shared double * b; } 
    10761076static assert(hasRawLocalAliasing!(S4)); 
    10771077// struct with an indirect pointer member 
    10781078struct S5 { S3 a; double b; } 
    10791079static assert(hasRawLocalAliasing!(S5)); 
    10801080struct S6 { S4 a; double b; } 
    10811081static assert(!hasRawLocalAliasing!(S6)); 
    10821082---- 
    10831083*/ 
    10841084 
    1085 private template hasRawLocalAliasing(T...) 
    1086 { 
    1087     enum hasRawLocalAliasing 
     1085private template hasRawUnsharedAliasing(T...) 
     1086{ 
     1087    enum hasRawUnsharedAliasing 
    10881088        = HasRawLocalPointerImpl!(RepresentationTypeTuple!(T)).result; 
    10891089} 
    10901090 
    10911091unittest 
    10921092{ 
    10931093// simple types 
    1094     static assert(!hasRawLocalAliasing!(int)); 
    1095     static assert(hasRawLocalAliasing!(char*)); 
    1096     static assert(!hasRawLocalAliasing!(shared char*)); 
     1094    static assert(!hasRawUnsharedAliasing!(int)); 
     1095    static assert(hasRawUnsharedAliasing!(char*)); 
     1096    static assert(!hasRawUnsharedAliasing!(shared char*)); 
    10971097// references aren't raw pointers 
    1098     static assert(!hasRawLocalAliasing!(Object)); 
    1099     static assert(!hasRawLocalAliasing!(int)); 
     1098    static assert(!hasRawUnsharedAliasing!(Object)); 
     1099    static assert(!hasRawUnsharedAliasing!(int)); 
    11001100    struct S1 { int z; } 
    1101     static assert(!hasRawLocalAliasing!(S1)); 
     1101    static assert(!hasRawUnsharedAliasing!(S1)); 
    11021102    struct S2 { int* z; } 
    1103     static assert(hasRawLocalAliasing!(S2)); 
     1103    static assert(hasRawUnsharedAliasing!(S2)); 
    11041104    struct S3 { shared int* z; } 
    1105     static assert(!hasRawLocalAliasing!(S3)); 
     1105    static assert(!hasRawUnsharedAliasing!(S3)); 
    11061106    struct S4 { int a; int* z; int c; } 
    1107     static assert(hasRawLocalAliasing!(S4)); 
     1107    static assert(hasRawUnsharedAliasing!(S4)); 
    11081108    struct S5 { int a; shared int* z; int c; } 
    1109     static assert(!hasRawLocalAliasing!(S5)); 
     1109    static assert(!hasRawUnsharedAliasing!(S5)); 
    11101110    struct S6 { int a; int z; int c; } 
    1111     static assert(!hasRawLocalAliasing!(S6)); 
     1111    static assert(!hasRawUnsharedAliasing!(S6)); 
    11121112    struct S7 { int a; Object z; int c; } 
    1113     static assert(!hasRawLocalAliasing!(S7)); 
     1113    static assert(!hasRawUnsharedAliasing!(S7)); 
    11141114    union S8 { int a; int b; } 
    1115     static assert(!hasRawLocalAliasing!(S8)); 
     1115    static assert(!hasRawUnsharedAliasing!(S8)); 
    11161116    union S9 { int a; int * b; } 
    1117     static assert(hasRawLocalAliasing!(S9)); 
     1117    static assert(hasRawUnsharedAliasing!(S9)); 
    11181118    union S10 { int a; shared int * b; } 
    1119     static assert(!hasRawLocalAliasing!(S10)); 
     1119    static assert(!hasRawUnsharedAliasing!(S10)); 
    11201120    typedef int* S11; 
    1121     static assert(hasRawLocalAliasing!(S11)); 
     1121    static assert(hasRawUnsharedAliasing!(S11)); 
    11221122    typedef shared int* S12; 
    1123     static assert(hasRawLocalAliasing!(S12)); 
     1123    static assert(hasRawUnsharedAliasing!(S12)); 
    11241124    enum S13 { a }; 
    1125     static assert(!hasRawLocalAliasing!(S13)); 
     1125    static assert(!hasRawUnsharedAliasing!(S13)); 
    11261126    // indirect members 
    11271127    struct S14 { S9 a; int b; } 
    1128     static assert(hasRawLocalAliasing!(S14)); 
     1128    static assert(hasRawUnsharedAliasing!(S14)); 
    11291129    struct S15 { S10 a; int b; } 
    1130     static assert(!hasRawLocalAliasing!(S15)); 
     1130    static assert(!hasRawUnsharedAliasing!(S15)); 
    11311131    struct S16 { S6 a; int b; } 
    1132     static assert(!hasRawLocalAliasing!(S16)); 
    1133     static assert(hasRawLocalAliasing!(int[string])); 
    1134     static assert(!hasRawLocalAliasing!(shared(int[string]))); 
    1135     static assert(!hasRawLocalAliasing!(immutable(int[string]))); 
     1132    static assert(!hasRawUnsharedAliasing!(S16)); 
     1133    static assert(hasRawUnsharedAliasing!(int[string])); 
     1134    static assert(!hasRawUnsharedAliasing!(shared(int[string]))); 
     1135    static assert(!hasRawUnsharedAliasing!(immutable(int[string]))); 
    11361136} 
    11371137 
    11381138/* 
    11391139Statically evaluates to $(D true) if and only if $(D T)'s 
    11401140representation includes at least one non-immutable object reference. 
    11411141*/ 
    11421142 
    11431143private template hasObjects(T...) 
    11441144{ 
    11451145    static if (T.length == 0) 
     
    11611161            hasObjects!(T[1 .. $]); 
    11621162    } 
    11631163} 
    11641164 
    11651165/* 
    11661166Statically evaluates to $(D true) if and only if $(D T)'s 
    11671167representation includes at least one non-immutable non-shared object 
    11681168reference. 
    11691169*/ 
    11701170 
    1171 private template hasLocalObjects(T...) 
     1171private template hasUnsharedObjects(T...) 
    11721172{ 
    11731173    static if (T.length == 0) 
    11741174    { 
    1175         enum hasLocalObjects = false; 
     1175        enum hasUnsharedObjects = false; 
    11761176    } 
    11771177    else static if (is(T[0] U == typedef)) 
    11781178    { 
    1179         enum hasLocalObjects = hasLocalObjects!(U, T[1 .. $]); 
     1179        enum hasUnsharedObjects = hasUnsharedObjects!(U, T[1 .. $]); 
    11801180    } 
    11811181    else static if (is(T[0] == struct)) 
    11821182    { 
    1183         enum hasLocalObjects = hasLocalObjects!( 
     1183        enum hasUnsharedObjects = hasUnsharedObjects!( 
    11841184            RepresentationTypeTuple!(T[0]), T[1 .. $]); 
    11851185    } 
    11861186    else 
    11871187    { 
    1188         enum hasLocalObjects = (is(T[0] == class) && 
     1188        enum hasUnsharedObjects = (is(T[0] == class) && 
    11891189                                !is(T[0] == immutable) && !is(T[0] == shared)) || 
    1190             hasLocalObjects!(T[1 .. $]); 
     1190            hasUnsharedObjects!(T[1 .. $]); 
    11911191    } 
    11921192} 
    11931193 
    11941194/** 
    11951195Returns $(D true) if and only if $(D T)'s representation includes at 
    11961196least one of the following: $(OL $(LI a raw pointer $(D U*) and $(D U) 
    11971197is not immutable;) $(LI an array $(D U[]) and $(D U) is not 
    11981198immutable;) $(LI a reference to a class type $(D C) and $(D C) is not 
    1199 immutable.) $(LI an associative array that is not immutable.)) 
     1199immutable.) $(LI an associative array that is not immutable.) 
     1200$(LI a delegate.)) 
    12001201*/ 
    12011202 
    12021203template hasAliasing(T...) 
    12031204{ 
    1204     enum hasAliasing = hasRawAliasing!(T) || hasObjects!(T); 
     1205    enum hasAliasing = hasRawAliasing!(T) || hasObjects!(T) || 
     1206        anySatisfy!(isDelegate, T); 
    12051207} 
    12061208 
    12071209unittest 
    12081210{ 
    12091211    struct S1 { int a; Object b; } 
    12101212    static assert(hasAliasing!(S1)); 
    12111213    struct S2 { string a; } 
    12121214    static assert(!hasAliasing!(S2)); 
    12131215    struct S3 { int a; immutable Object b; } 
    12141216    static assert(!hasAliasing!(S3)); 
    12151217    struct X { float[3] vals; } 
    12161218    static assert(!hasAliasing!X); 
     1219    static assert(hasAliasing!(uint[uint])); 
     1220    static assert(!hasAliasing!(immutable(uint[uint]))); 
     1221    static assert(hasAliasing!(void delegate())); 
    12171222} 
    12181223 
    12191224/** 
    12201225Returns $(D true) if and only if $(D T)'s representation includes at 
    12211226least one of the following: $(OL $(LI a raw pointer $(D U*);) $(LI an 
    12221227array $(D U[]);) $(LI a reference to a class type $(D C).) 
    1223 $(LI an associative array.)
     1228$(LI an associative array.) $(LI a delegate.)
    12241229 */ 
    12251230 
    12261231template hasIndirections(T) 
    12271232{ 
    12281233    enum hasIndirections = hasIndirectionsImpl!(RepresentationTypeTuple!T); 
    12291234} 
    12301235 
    12311236template hasIndirectionsImpl(T...) 
    12321237{ 
    12331238    static if (!T.length) 
    12341239    { 
    12351240        enum hasIndirectionsImpl = false; 
    12361241    } 
    12371242    else 
    12381243    { 
    12391244        enum hasIndirectionsImpl = isPointer!(T[0]) || isDynamicArray!(T[0]) || 
    12401245            is (T[0] : const(Object)) || isAssociativeArray!(T[0]) || 
    1241             hasIndirectionsImpl!(T[1 .. $]); 
     1246            isDelegate!(T[0]) || hasIndirectionsImpl!(T[1 .. $]); 
    12421247    } 
    12431248} 
    12441249 
    12451250unittest 
    12461251{ 
    12471252    struct S1 { int a; Object b; } 
    12481253    static assert(hasIndirections!(S1)); 
    12491254    struct S2 { string a; } 
    12501255    static assert(hasIndirections!(S2)); 
    12511256    struct S3 { int a; immutable Object b; } 
    12521257    static assert(hasIndirections!(S3)); 
    12531258    static assert(hasIndirections!(int[string])); 
    1254 
     1259    static assert(hasIndirections!(void delegate())); 
     1260
     1261 
     1262// These are for backwards compatibility, are intentionally lacking ddoc, 
     1263// and should eventually be deprecated. 
     1264alias hasUnsharedAliasing hasLocalAliasing; 
     1265alias hasRawUnsharedAliasing hasRawLocalAliasing; 
     1266alias hasUnsharedObjects hasLocalObjects; 
    12551267 
    12561268/** 
    12571269Returns $(D true) if and only if $(D T)'s representation includes at 
    12581270least one of the following: $(OL $(LI a raw pointer $(D U*) and $(D U) 
    12591271is not immutable or shared;) $(LI an array $(D U[]) and $(D U) is not 
    12601272immutable or shared;) $(LI a reference to a class type $(D C) and 
    1261 $(D C) is not immutable or shared.)) 
     1273$(D C) is not immutable or shared.) $(LI an associative array that is not 
     1274immutable or shared.) $(LI a delegate that is not shared.)) 
    12621275*/ 
    12631276 
    1264 template hasLocalAliasing(T...) 
    1265 
    1266     enum hasLocalAliasing = hasRawLocalAliasing!(T) || hasLocalObjects!(T); 
     1277template hasUnsharedAliasing(T...) 
     1278
     1279    enum hasUnsharedAliasing = hasRawUnsharedAliasing!(T) || 
     1280        anySatisfy!(unsharedDelegate, T) || hasUnsharedObjects!(T); 
     1281
     1282 
     1283private template unsharedDelegate(T) 
     1284
     1285    enum bool unsharedDelegate = isDelegate!T && !is(T == shared); 
    12671286} 
    12681287 
    12691288unittest 
    12701289{ 
    12711290    struct S1 { int a; Object b; } 
    1272     static assert(hasLocalAliasing!(S1)); 
     1291    static assert(hasUnsharedAliasing!(S1)); 
    12731292    struct S2 { string a; } 
    1274     static assert(!hasLocalAliasing!(S2)); 
     1293    static assert(!hasUnsharedAliasing!(S2)); 
    12751294    struct S3 { int a; immutable Object b; } 
    1276     static assert(!hasLocalAliasing!(S3)); 
     1295    static assert(!hasUnsharedAliasing!(S3)); 
    12771296 
    12781297    struct S4 { int a; shared Object b; } 
    1279     static assert(!hasLocalAliasing!(S4)); 
     1298    static assert(!hasUnsharedAliasing!(S4)); 
    12801299    struct S5 { char[] a; } 
    1281     static assert(hasLocalAliasing!(S5)); 
     1300    static assert(hasUnsharedAliasing!(S5)); 
    12821301    struct S6 { shared char[] b; } 
    1283     static assert(!hasLocalAliasing!(S6)); 
     1302    static assert(!hasUnsharedAliasing!(S6)); 
    12841303    struct S7 { float[3] vals; } 
    1285     static assert(!hasLocalAliasing!(S7)); 
     1304    static assert(!hasUnsharedAliasing!(S7)); 
     1305 
     1306    static assert(hasUnsharedAliasing!(uint[uint])); 
     1307    static assert(hasUnsharedAliasing!(void delegate())); 
     1308    static assert(!hasUnsharedAliasing!(shared(void delegate()))); 
    12861309} 
    12871310 
    12881311/** 
    12891312 True if $(D S) or any type embedded directly in the representation of $(D S) 
    12901313 defines an elaborate copy constructor. Elaborate copy constructors are 
    12911314 introduced by defining $(D this(this)) for a $(D struct). (Non-struct types 
    12921315 never have elaborate copy constructors.) 
    12931316 */ 
    12941317template hasElaborateCopyConstructor(S) 
    12951318{ 
     
    27572780 
    27582781    auto dgbar = &bar; 
    27592782    static assert(! isFunctionPointer!(dgbar)); 
    27602783    static assert(! isFunctionPointer!(void delegate())); 
    27612784    static assert(! isFunctionPointer!(foo)); 
    27622785    static assert(! isFunctionPointer!(bar)); 
    27632786 
    27642787    static assert(!isFunctionPointer!((int a) {})); 
    27652788} 
    27662789 
     2790/** 
     2791Detect whether $(D T) is a delegate. 
     2792*/ 
     2793template isDelegate(T...) 
     2794if(staticLength!T == 1) 
     2795{ 
     2796    enum bool isDelegate = is(T[0] == delegate); 
     2797} 
     2798 
     2799unittest 
     2800{ 
     2801    static assert(isDelegate!(void delegate())); 
     2802    static assert(isDelegate!(uint delegate(uint))); 
     2803    static assert(isDelegate!(shared uint delegate(uint))); 
     2804    static assert(!isDelegate!(uint)); 
     2805    static assert(!isDelegate!(void function())); 
     2806} 
     2807 
    27672808 
    27682809/** 
    27692810Detect whether symbol or type $(D T) is a function, a function pointer or a delegate. 
    27702811 */ 
    27712812template isSomeFunction(/+@@@BUG4217@@@+/T...) 
    27722813    if (/+@@@BUG4333@@@+/staticLength!(T) == 1) 
    27732814{ 
    27742815    enum bool isSomeFunction = isSomeFunction_bug4333!(T).isSomeFunction; 
    27752816} 
    27762817private template isSomeFunction_bug4333(T...)