Unpacking Slices

Ali Çehreli acehreli at yahoo.com
Mon Jun 14 19:17:58 UTC 2021


On 6/14/21 11:08 AM, Justin Choi wrote:
> Is there any shortcut for unpacking slices like I'd want to do in a 
> scenario like this?
> `info = readln.strip.split;`
> `string a = info[0], b = info[1], c = info[2];`

D does not have automatic unpacking. Here is a quick, dirty, and fun 
experiment:

struct Unpack(Args...) {
   static string typeName(size_t n)() {
     return Args[n].stringof;
   }

   static char varName(size_t n) {
     return cast(char)('a' + n);
   }

   // Variable declarations
   static foreach (n; 0 .. Args.length) {
     mixin (typeName!n ~ ' ' ~ varName(n) ~ ';');
   }

   // Get by variable number
   auto get(size_t n)() {
     mixin ("return " ~ varName(n) ~ ';');
   }

   // Set by variable number
   auto set(size_t n, T)(T value) {
     mixin (varName(n) ~ " = value;");
   }
}

template unpack(Args...) {
   auto unpack(R)(R range) {
     auto result = Unpack!(Args)();
     static foreach (n; 0 .. Args.length) {
       import std.range : front, popFront;
       result.set!n(range.front);
       range.popFront();
     }
     return result;
   }
}

import std.stdio;
import std.string;

void main() {
   auto info = readln.strip.split;
   auto u = info.unpack!(string, string, string);

   // Variables are accessed by name as a, b, etc. or by number:
   assert(u.a == u.get!0);
   assert(u.b == u.get!1);
   assert(u.c == u.get!2);
}


When all variable types are the same, the usage can be improved to allow 
e.g.

   info.unpack!(3, string)

That's not implemented yet. :)

Ali


More information about the Digitalmars-d-learn mailing list