@@ -66,6 +66,11 @@ $(BUGSTITLE Library Changes,
6666 contract preconditions.)
6767 $(LI $(RELATIVE_LINK2 headconst, `Final` was added to
6868 `std.experimental.typecons`))
69+ $(LI $(RELATIVE_LINK2 inner-class, `std.traits.isInnerClass` was added to
70+ identify nested classes with an accessible `outer` pointer))
71+ $(LI $(RELATIVE_LINK2 emplace-inner-class, `std.conv.emplace` no longer allows
72+ to emplace classes directly nested inside other classes without specifying a
73+ suitable `outer` pointer))
6974)
7075
7176$(BUGSTITLE Library Changes,
@@ -358,6 +363,59 @@ assert(a[0] == 42);
358363-------
359364)
360365
366+ $(LI $(LNAME2 inner-class, `std.traits.isInnerClass` was added to identify
367+ nested classes with an accessible `outer` pointer)
368+ $(P Classes, that are nested inside other classes (and not inside functions)
369+ and that don't define any `outer` symbol, have an `outer` field which allows
370+ to get and even set the instance of the outer class they are nested in.
371+ $(REF isInnerClass, std, traits) allows to identify them. The types satisfying
372+ `isInnerClass` are a subset of the ones satisfying `isNested`, as the latter
373+ includes classes and structures nested inside functions or that redefine `outer`.
374+ )
375+ -------
376+ class Outer
377+ {
378+ class Inner1 { }
379+ class Inner2
380+ {
381+ int outer; // redefines outer, so the Outer instance is not accessible
382+ }
383+ static class Inner3 {} // static, thus not nested
384+ }
385+ static assert(isInnerClass!(Outer.Inner1));
386+ static assert(!isInnerClass!(Outer.Inner2));
387+ static assert(!isInnerClass!(Outer.Inner3));
388+ -------
389+ )
390+
391+ $(LI $(LNAME2 emplace-inner-class, `std.conv.emplace` no longer allows to emplace
392+ classes nested directly inside other classes without specifying a suitable `outer`
393+ pointer)
394+ $(P If a class is nested within another class (there's a new trait
395+ $(REF isInnerClass, std, traits) to check for this condition), `emplace` requires
396+ now the outer class instance as additional mandatory parameter. Before this
397+ change, emplacing did not require this parameter and access to variables of the
398+ outer class resulted in segmentation faults.
399+ )
400+ -------
401+ class Outer
402+ {
403+ int x;
404+ class Inner
405+ {
406+ auto getX() { return x; }
407+ }
408+ }
409+ Outer outer = new Outer();
410+
411+ // auto inner = buf.emplace!(Outer.Inner)(); // this is no longer allowed
412+ auto inner = buf.emplace!(Outer.Inner)(outer); // use this instead
413+
414+ auto x = inner.getX(); // this used to cause a segmentation fault;
415+ // now it works as expected
416+ -------
417+ )
418+
361419)
362420
363421Macros:
0 commit comments