Thread overview
Meta kodlama üzerine bir soru
Mar 19, 2023
Salih Dincer
Mar 19, 2023
Salih Dincer
Mar 19, 2023
Ali Çehreli
March 19, 2023

Emin değilim, belki bir cevap olacak!

Eğer bu yazdıklarımı okuyorsanız cevabı henüz tam bulamamış veya anlayamamış olmalıyım. Zaten bulursam büyük ihtimalle göndermemiş olacağım, yani aşağıdakiler boşa kürek hani :)

Adım adım denemeliyim...

struct Uzun_isimli_ve_yazmak_zahmetli(T) { T i; }
alias Yeni(T) = Uzun_isimli_ve_yazmak_zahmetli!T;

Değerli Ali hocamdan en son bu yukardaki ilk örneği öğrenmiştim. Takmaadların parametre alabildiğini bilmiyordum. Bu gerçekten hayatı kolaylaştırıyor ve kullanımı basit, şu şekilde:

Yeni!int n;
assert(n.i == 0);

Eee bu da gayet basit, anlamayanı döverler :)

alias Unconst(T : const U, U) = U;

Kullanımına geçmeden, adeta bunun "Proto Template" olduğunu belirtmeliyim. Evet, bu terimi ben uydurdum çünkü bende yarattığı his bu ve gerçekten çok güzel, leziz:

alias cType = typeof(c);
Unconst!cType Int;
Int = 2;

Hayatı kolaylaştıran bir başka öğe: is ile typeof birleşimi. Evet, artık şablonlara girdik. Böyle bir şey zaten vardı da ben mi uydurdum onu bilmiyorum ama kullanıyorum:

alias isTypeOf = ito;
template ito(alias value)
{
  alias T = typeof(value);
  enum ito(U) = is(U == T);
}

Kullanmak için yakın markaja aldığım şablona (bir de kardeşi var allSatisfy) ihtiyacımız olabilir.

import std.meta : anySatisfy;
  static assert(!anySatisfy!(isTypeOf!Int, ubyte, uint, ulong));
  static assert(anySatisfy!(isTypeOf!Int, ubyte, int, ulong));

Yaptığı iş çok basit: İlk parametreyle sırasıyla sonraki parametreleri karşılaştırmak ve herhangi biri uyuşursa true döndürmek. Dikkat ederseniz önceki örneklerdeki const(c)'den türeyen Int'i kullandım. İlk assertdeki ünleme (!) dikkat edin. Karşılaştırılabilecek int olmadığına göre false döndü.

Eğer std.meta'yı incelerseniz runtime'deki bir şablona ulaşıyorsunuz kaynağı şu:

import core.internal.traits : anySatisfy;

// ve çekirdek kod bir foreach içinde:
template anySatisfy(alias F, A...)
{
  static foreach(T; A)
  {
    static if(!is(typeof(anySatisfy) == bool) && F!T)
    {
      enum anySatisfy = true;
    }
  }
  static if(!is(typeof(anySatisfy) == bool))
  {
    enum anySatisfy = false;
  }
}

Bu kadar yeter çünkü sıkıldım :)

Soruya gelip çıkıyorum, biz sadece bunu bir döngü ile halledemez miydik? Yani bize lazım olan, foreach içinde dönen bir static if is() değil mi? Tıpkı Ali hocanın staticMapN()'de kodladığı gibi akıllı bir şeyler olurdu sanki!

Bu işler bir yılan gibi bu kadar uzun ve karmaşık olmamalı :)

March 19, 2023

On Sunday, 19 March 2023 at 11:51:36 UTC, Salih Dincer wrote:

>

... sıkıldım :)

Soruya gelip çıkıyorum, biz sadece bunu bir döngü ile halledemez miydik? Yani bize lazım olan ...

:)

Biraz daha sabra ihtiyacım varmış çünkü "sıkıldım" demekle aslında önümdeki merdiven gibi dizilen kolaylığı göremedim. Zirveye çok yakınmışım, erken pes ettiğim için üzgünüm! İşte çözümüm:

template whichIn(alias value, A...) {
  alias T = typeof(value);
  static foreach(U; A) {
    static if(!is(typeof(whichIn) == bool)
            && is(U == T)
    ) enum whichIn = true;
  }
  static if(!is(typeof(whichIn) == bool))
    enum whichIn = false;
}

enum : byte { num = 123 }
pragma(msg, whichIn!(num, uint, int, ushort, byte)); // true

Lütfen öcekiyle birlikte iki kodu da karşılaştırınız. Çünkü anySatisfy()'daki F'e dikkat, meğer o bir alias'mış. Yani aslında biz ona alias func ismi de verebilirdik! Diğer şablonu kalbine gömerdik :)

Dip Not: && ile önceki sonuca bakmak akıllıca. Çünkü true yakalandığında bir daha 2. şarta bakılmaz. Çok temel mevzuyu burada görmekteyiz. Bu arada, şablonun ismi ne olsun? Sanırım which'li bir şey gider?

Başarılar...

March 19, 2023
On 3/19/23 06:02, Salih Dincer wrote:

> İşte çözümüm:

Güzel. :)

> ```d
> template whichIn(alias value, A...) {
>    alias T = typeof(value);
>    static foreach(U; A) {
>      static if(!is(typeof(whichIn) == bool)
>              && is(U == T)

Oradaki 'whichIn' neyi temsil ediyor? İçinde bulunduğumuz şablon ise bir türü yoktur çünkü bu şablonun neyi temsil ettiğinin kararını vermeye çalışıyoruz.

O parçayı çıkarınca da aynı çalıştığına göre orada bir gariplik var. ;)

     static if(is(U == T)
     ) enum whichIn = true;

Senin yazdığın gibi yazdım ama kendim her zaman için küme parantezlerini de kullanırdım:

     static if(is(U == T)) {
         enum whichIn = true;
     }

> şablonun ismi ne olsun? Sanırım which'li bir şey
> gider?

isOneOf, typeIsOneOf, ... (?)

Ali