Forum: Ders Arası RSS
Şablonlar ile yığın sınıfı
Sayfa:  önceki  1  2  3  4  sonraki 
Avatar
Salih Dinçer #16
Üye Ock 2012 tarihinden beri · 1912 mesaj · Konum: İstanbul
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Yanıtlanan mesaj ID 6499
zafer:
    public void Push(T)(T deger)
    {
        if (konum < yigin.length)
        {
            throw new Exception("Yigin dolu");
        }
 
        konum++;
        yigin[konum] = deger;
    }

Evet, konum degişkeni burada Yıgın sınıfının üye degişkeni ve görevi yıgın üzerinde bulunulan konumu göstermek. Yıgın yapısı için biz bir dizi kullandık, dizimiz sıfırdan başlıyor ve kullanıcının girdigi değer kadar bir büyüklüğe sahip. Örneğin kullanıcı on elemanlı bir yıgın oluşturmak isterse bizim yıgın dizimiz en fazla on elemanlı oluyor.

Bu duruma göre konum degişkeni yıgın dizisi üzerindekl geçerli konumları göstermesi gerekiyorsa her zaman yigin dizisini boyutundan küçük olmak zorunda.
Sabahleyin salim kafayla bakmak üzere bu işlevin doğru çalışmadığını belirtmeliyim. Çünkü son halinde her zaman "Yığın Dolu" hatası alıyorum. Şu an şantiyedeki cabinet rack'ın karşısında olduğum ve dizlerim ağrıdığı (!) için fazla bakamıyorum.

Dip Not: Bu arada Ali hocam da bugün dönüyor. Kendisine hayırlı yolculuklar dilerim.

Kolay gelsin...
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)
Kadir Can #17
Üye Haz 2010 tarihinden beri · 413 mesaj
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Yanıtlanan mesaj ID 6499
zafer:
    public void Push(T)(T deger)
    {
        if (konum < yigin.length)
        {
            throw new Exception("Yigin dolu");
        }
 
        konum++;
        yigin[konum] = deger;
    }
Bu duruma göre konum degişkeni yıgın dizisi üzerindekl geçerli konumları göstermesi gerekiyorsa her zaman yigin dizisini boyutundan küçük olmak zorunda.
İşte hata burada, konum her zaman yigin dizisinin boyutundan küçük olmalı; ama biz küçükken hata atıyoruz.Yani Push() her çağrıldığında hata atıyor.Aşağıdaki haliyle doğru çalışıyor.
    public void Push(T)(T deger)
    {
        if (konum == (yigin.length - 1))
        {
            throw new Exception("Yigin dolu");
        }
 
        konum++;
        yigin[konum] = deger;
    }
clear() işlevi de aklımda.Hemen başlıyorum. :)
Kadir Can #18
Üye Haz 2010 tarihinden beri · 413 mesaj
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Clear() işlevini ekledim; ama şu haliyle biraz masraflı.Aslında sanırım yaptığım olması gerekendi, yani yığını temizlediğimizde elemanların kaybolmaması, sadece kullanıcıyı gösterilmemesi gerekiyor.Bu konuda yorumlarınızı bekliyorum.
import std.stdio;
import std.exception;
import std.conv;
 
class Yigin(T) 
{
    private int konum;
    private T[] yigin;
    private Yigin yedek;
 
    public this(int kapasite) 
    {
        enforce(kapasite >=0, "Yigin buyuklugu negatif olamaz!");
        yigin.length = kapasite;
        konum = -1;
    }
 
    invariant()
    {
        int yiginKapasitesi = yigin.length;
        assert(konum < yiginKapasitesi);
    }
 
    public void Push(T)(T deger)
    {
        if (konum == (yigin.length - 1))
        {
            throw new Exception("Yigin dolu");
        }
 
        konum++;
        yigin[konum] = deger;
    }
 
    public T Pop()
    {
        if (konum == -1)
        {
            throw new Exception("Yigin bos");
        }
 
        return yigin[konum--];
    }
 
    bool empty() const
    {
        // Aralıktaki eleman mevcudunu denetler. 
        // true ise eleman bitmiştir.
        return (konum < 0);
    }
 
    void popFront()
    {
        // Bir sonrakine geçmek, mevcut eleman
        // sıramızda her defasında sondan bir tane
        // dışarı çıkarmak
        --konum;
    }
 
    string front() const
    {
        // ilgili konumdaki elemanı bize verir
        return yigin[konum];
    }
 
    public void  Clear()
    {
        yedek = new Yigin!T(yigin.length);
        yedek.yigin[] = yigin[];
        yigin = yigin.init;
    }
    
    public string  eskiyiDöndür() const
    {
        string sonuç;
        foreach(eleman; yedek.yigin)
        {
            sonuç ~= to!string(eleman) ~ " ";
        }
        return sonuç;
    }
}
 
void main()
{
    Yigin!(string) stack = new Yigin!(string)(10);
 
    foreach(sayi; 0..10)
    {
        stack.Push(to!string(sayi)); 
    }
 
    foreach (kelime; stack)
    {
        writeln("Deger : ", kelime);   
    }
    
    stack.Clear();
 
    writeln(stack.eskiyiDöndür());
}
Yığın şablonunu int ile de çağırabilirdim ama deneme kodu olduğu için ne kadar fazla şey görsek o kadar iyidir diyorum. :)
Avatar
Salih Dinçer #19
Üye Ock 2012 tarihinden beri · 1912 mesaj · Konum: İstanbul
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Kadir, ben de yolda düşünüyorken aklıma koşut işlemler ve sürekli veri pompalanan bir bellek yapısı geldi. Yatmadan bir şeyler kodlayım dedim ve şu aşağıdaki program meydana geldi. Henüz buffer sürekli tazelenmiyor ve kilit işlemini bitirmedim. Ayrıca veriyi sondan değil girdiği sırayla (alıştığımız şekle göre ters) işliyor. İşlemler uzun sürsün diye de basitinden asalları sayan işlev koydum. Şimdi sıra kilitleme işleminde çünkü veri gelirken ve dizi kısalırken işler karışabilir, öyle değil mi?
/*
 invertStack.d (05.07.2012)
*/
import std.exception, std.stdio;
import std.parallelism, std.random;
 
class Stack (T){
    T[] buffer;
    bool lock;
    
    void push(T data) {
        if (!lock) buffer ~= data;
    }
    T fetch() {
        if(buffer.length == 0) {
            throw new Exception("ERROR(1): STACK EMPTY");
        }
        lock = true;
        scope(exit) lock = false;
        auto temp = buffer[0];
        buffer = buffer[1..$];
        return temp;
        
    }
    bool clear() {
        buffer = buffer[0..0];
        return true;
    }
    bool isEmpty() {
        return buffer.length > 0 ? true : false;
    }
}
void asalSay(int i, int p) {
    int xSay = 1;
    
    for(int k = 3; k <= p; k += 2) {
        if(isPrime(k)) {
            xSay++;
        }
    }
    writefln(" # %d numbers between [0 - %d] "
             "of %d primes found... ", i, p, xSay);
}
bool isPrime(int p) {
    if(p % 2 == 0) {
        return false;
    }
    for(int n = 3; n * n <= p; n += 2) {
        if(p % n == 0) {
            return false;
        }
    }
    return true;
}
void main() {
    auto stack = new Stack!int;
 
    for(int i; i < 100; i++) {
        stack.push(uniform(0, 1_000_000));
    }
    for(int index; stack.isEmpty; index++) {
        auto xTask = task!asalSay(index, stack.fetch);
        xTask.executeInNewThread();
    }
}
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)
Bu mesaj 2 defa değişti; son değiştiren: Salih Dinçer; zaman: 2012-07-05, 22:56.
Kadir Can #20
Üye Haz 2010 tarihinden beri · 413 mesaj
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
@Salih;
Şu an için bu kod beni aşıyor, koşut işlemlere gelemedim. :(
Kodlar gayet güzel görünüyor, şu an D.ershane'den çalışıyorum, vaktim olduğunda koda biraz güvenlik eklemeyi düşünüyorum.Bakalım bu sefer güvenlik olanaklarını tamı tamına tasarlayabilecek miyim? :)
Sanırım aslen yapmak istediğin veri giriş çıkışının beklememesi, değil mi?Yani sürekli ekleme ve çıkarma yapılacak, okumalar sırasında da kilitlenecek, bu sayede değişme olmadığı için veri kaybı olmayacak.Doğru mu anlamışım?
Anladığım kadarıyla burada stack boşalana kadar gelen sayıların koşut olarak asal olup olmadığını denetliyoruz, değil mi?
Avatar
Salih Dinçer #21
Üye Ock 2012 tarihinden beri · 1912 mesaj · Konum: İstanbul
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Tam olarak doğru anlamışsın. Aslında işlemciler çok hızlı olduğu için her rasgele üretilen sayıya kadar kaç tane asal sayı olduğunu saydırıyorum. Böylece işlemci defalarca ve defalarca hep aynı işlemi yapıyor. Ancak burada önemli bir sorun var:

İkinci döngü şak diye kuruluyor. Dolayısıyla bir yandan stack'a veri eklesem de arkadaki thread'lar çalışmaya devam edecek. Öyle bir şey yapmalı ki stack yine dolduğunda bir event oluşsun ve yeni thread'lar meydana gelsin. İşte bu beni de aşıyor...:)

Önemli !!! Az önce yukarıdaki kodu 64 bit sistemde ve emin olmak niyetiyle "-m64 -release" parametreleri ile derledim ve binary dosya çalıştırılamadı. Herhalde koşullu programlama ile ilgili bir şeyler karışmış olmalı dedim kendi kendime. Sonra import bölümündeki kütüphaneler ile birlikte koddaki bu bölümü kaldırdım ve yine aynı hata! Sanırım -m64'de bir şeyler karışıyor ama farklı binary dosyası oluştuğuna eminim. Çünkü -m32 ile -m64 arasında 100 KB. bir fark var. Bu arada sistem Ubuntu, DMD 2.059 ve main() en son şu şekildeydi:
void main() {
    auto stack = new Stack!int;
 
    for(int i; i < 100; i++) {
        stack.push(uniform(0, 1_000_000));
    }
    for(int index; stack.isEmpty; index++) {
        asalSay(index, stack.fetch);
    }
}
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)
Bu mesaj 3 defa değişti; son değiştiren: Salih Dinçer; zaman: 2012-07-05, 23:37.
zafer #22
Üye Tem 2009 tarihinden beri · 700 mesaj · Konum: Ankara
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Benim kendimce kodlamada gördüğüm eksiklikler;

    • Yığıt sınıfının bellek üye degişkenine program içinden erişim tehlikeli. Örneğin konum değeri beş olduğu bir durumda ben program içinden bellek dizisine erişip bir elemanı silersem Yığıt nesnesinin tutarlılığı bozulmuş olacaktır.

    • bellek = bellek[0..0]; kısmını anlamadım Salih, buradaki amaç bellek dizisini boşaltmak mı?

    • if(temizle) goto atla; temizle metodu her zaman true döndürdügüne göre bu satırın altındaki kodlar hiç çalışmayacaktır. (goto deyiminin işlemi atla: etiketine gönderdiğini varsayıyorum.) Ayrıca bu bölümde oluşturulan yığıt ekrana hiç yazılmıyor?

Benim görebildiklerim bunlar, elbette başka arkadaşlar daha başka yönlerden kodu inceliyip başka tavsiyeler verebilir. Bunların dışında bence güzel olmuş eline sağlık Salih.

Salih Dinçer:
Çünkü public gibi davranıyor.

Bu durum sınıf ile test kodunun aynı modülde olmasından kaynaklanıyor. Eger sınıfı başka bir modüle taşırsan o zaman erişim belirteçlerinin etkisini görebilirsin.

canalpay:
Çok fazla kod ve yazı yazılmış okuyamadım :-)

Hatırladın mı Can havalanı binasına baktıgımızda ne kadar güzel ve büyük bir yapı diye konuşmuştuk. İlk bakışta büyük bir kod parçası sizi ürkütebilir ancak o büyük kod parçasıda tek bir satır ile başlayıp bu hale gelmiştir. Uzun lafın kısası kodlar gözünü korkutmasın al yapıştır bir metin editörüne (veya Divid'e :)) sonra yazıcıdan çıktı al ve bir derleyici gibi giriş metodundan başla ve devam et, o sana yolu gösterecektir ;)

Kadir Can:
ama biz küçükken hata atıyoruz.

Kadir düzeltme için teşekkürler. Bu küçük ve basit bir metot bile insanın nasıl hatalı kod yazabilecegine çok güzel bir örnek oldu. Ben bu metodun çıktısını alıp işyerimdeki panoma çiviledim ;)

public void  Clear()
{
    yedek = new Yigin!T(yigin.length);
    yedek.yigin[] = yigin[];
    yigin = yigin.init;
}

Kadir, Clear() metodunu güzel gerçekleştirmişsin. Özellikle yigin = yigin.init; kısmı benim çok hoşuma gitti. Doğrusu ben bu işlem için bir döngü kullanırdım sanırım, bu çok daha temiz ve güzel bir kodlama olmuş. Yedekleme konusunda ise ben şöyle düşünüyorum; Yıgın sınıfı bir hizmet sınıfı amacı geliştiriciye yıgın yapısını kullanabilme imkanını daha kolay bir şekilde sağlamak. Ayrıca yıgın sınıfının temel görevi mevcut yıgın yapısının yönetimini sağlamak. Bundan dolayı geliştirici yıgın sınıfının mevcut halini saklamak istiyorsa bu onu ilgilendirmeli yıgın sınıfı olarak bizi degil. Yani en basit manada Clear() metodu yıgını temizlemeli, verilerin durumu onların esas sahibi olan geliştiriciyi ilgilendirir bizi degil ;)
https://github.com/zafer06 - depo
Kadir Can #23
Üye Haz 2010 tarihinden beri · 413 mesaj
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Haklısın @Zafer, o sebeple işlev şu hale geldi, çok uzun olduğu için kodun tamamını kopyalamıyorum.
public void  Clear()
{
    yigin = yigin.init;
}
@Salih;
Bende de "Internal error: msc 259" gibi bir hata verdi.
zafer #24
Üye Tem 2009 tarihinden beri · 700 mesaj · Konum: Ankara
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Yanıtlanan mesaj #21
Salih Dinçer:
Öyle bir şey yapmalı ki stack yine dolduğunda bir event oluşsun ve yeni thread'lar meydana gelsin.

Salih, anladığım kadarıyla bazı işlerin dinamik olarak yapılmasını istiyorsun. Dinamik olarak yeni diziler oluşturup bunları rastgele dolduran ve bir listeye ekleyen bir kod hazırladım. Belki bir yardımı olur diye düşünüyorum. Senin belirttigin gibi her dizi dolduğunda yeni bir dizi hazırlanıp onun üzerinde çalışılıyor.

import std.stdio;
import std.random;
import std.container;
 
void main() 
{
    SList!(int[]) diziListe;
 
    for (int i = 0; i < 100; ++i)
    {
        // Benim için yeni bir dizi hazırla
        // int tipinde ve 5 elemanlı olsun
        int[] dizi = new int[5];
 
        // Yeni diziye değerleri doldur.
        for (int j = 0; j < 5; ++j)
        {
            dizi[j] = uniform(0, 100);
        }
 
        // Dolu diziyi kaybetmemek için
        // listeye ekle
        diziListe.insert(dizi);
    }   
 
    // Listeyi yazalım, bakalım neler varmış.
    foreach (dizi; diziListe)
    {
        writefln("-> %s", dizi);
    }
}
https://github.com/zafer06 - depo
Avatar
Salih Dinçer #25
Üye Ock 2012 tarihinden beri · 1912 mesaj · Konum: İstanbul
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Yanıtlanan mesaj #22
zafer:
Yığıt sınıfının bellek üye degişkenine program içinden erişim tehlikeli. Örneğin konum değeri beş olduğu bir durumda ben program içinden bellek dizisine erişip bir elemanı silersem Yığıt nesnesinin tutarlılığı bozulmuş olacaktır.
Aslında bu yazdığım kodlar deneme kodu ve senin yazdığından farklı olarak konum değişkenini kullanmadan ters mantıkla çalıştırmayı denedim. Denemelerimden biri de private olarak işaretlenmiş bir üyeye neden erişebildiğim hakkındaydı. Zaten onu da modül mevzusuna bağlamışsın. Yoksa tutarsızlık olmaması için özellikle temizle() işlevini gerçekledim.

zafer:
bellek = bellek[0..0]; kısmını anlamadım Salih, buradaki amaç bellek dizisini boşaltmak mı?
Kadir .init ile temizlemiş ve bunu bilmiyordum. Ben ise 0 boyutlu bir dilim göndererek yaptım. İlginçtir konferansta bu .init olayını anlatmadım. Asıl eksiklik bu olmalı...:)

zafer:
if(temizle) goto atla; temizle metodu her zaman true döndürdügüne göre bu satırın altındaki kodlar hiç çalışmayacaktır. (goto deyiminin işlemi atla: etiketine gönderdiğini varsayıyorum.) Ayrıca bu bölümde oluşturulan yığıt ekrana hiç yazılmıyor?
Dediğim gibi bunlar bir deneme tıpkı devam eden satırlardaki lock olayı gibi.

Ek: Bu arada kodları 64 bitte derleyebilen oldu mu? Belki de benim sistemde bir sorun var...:(
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)
Bu mesaj 2 defa değişti; son değiştiren: Salih Dinçer; zaman: 2012-07-06, 05:39.
Avatar
Salih Dinçer #26
Üye Ock 2012 tarihinden beri · 1912 mesaj · Konum: İstanbul
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Yanıtlanan mesaj #24
zafer:
Salih, anladığım kadarıyla bazı işlerin dinamik olarak yapılmasını istiyorsun. Dinamik olarak yeni diziler oluşturup bunları rastgele dolduran ve bir listeye ekleyen bir kod hazırladım. Belki bir yardımı olur diye düşünüyorum. Senin belirttigin gibi her dizi dolduğunda yeni bir dizi hazırlanıp onun üzerinde çalışılıyor.
Teşekkürler,

Aslında mesajlaşarak paralel programlama olanaklarını kullanarak event mantığını oturtmak istiyorum. Çünkü artık çevremizdeki bir çok şey (-bknz. Action Script) bunun üzerine çalışmakta. Örneğin spawn() işlevine benzer bir kurucu işlev ile klavyeden stack'a veri aktaran thread olacak. Aynı zamanda stack'daki veriyi düzenli aralıklarda çeken bir uzunİşlev (asalSay gibi) çalışacak. Şimdi mesele şu:

Arka planda örneğin birer deste veriyi stack'dan alıp işlerken ben klavyeden stack'ı doldurabilmeliyim ve stack küçülürken bir şeyler karışmasın. Hatta kuyruktaki tüm görevler bittiğinde uzunİşlevi tetikleyecek; stack'a veri girişiyle meydana gelen başka bir event olmalı. Bu event'lar birbirleriyle çok güzel anlaşarak çalışmalı. Tıpkı mesajlaşarak yaptığımız paralel programlamadaki posta kutusu mantığı gibi.

Bunlar teorik olarak mümkün görünüyor...:)
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)
Bu mesaj Salih Dinçer tarafından değiştirildi; zaman: 2012-07-06, 09:32.
zafer #27
Üye Tem 2009 tarihinden beri · 700 mesaj · Konum: Ankara
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Salih Dinçer:
Bunlar teorik olarak mümkün görünüyor...:)

Pratik olarakta mümkün tabi ki. Ancak senin bahsettigin gibi sen klavyeden giriş yaparken başka bir işlemin yıgından bilgi alması yıgın yapısına uygun olmadıgı gibi sadece bir kaos yaratacaktır.

Benim anladıgım kadarıyla aslında senin istedigin yapı için kuyruk (queue) (http://e-bergi.com/2008/Eylul/Soyut-Veri-Yapilari) yapısı daha uygun görünüyor. Bir incele işini görüyorsa bir kuyruk sınıfı yazmaya başla bizde yardım ederiz ;)
https://github.com/zafer06 - depo
acehreli (Moderatör) #28
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Yanıtlanan mesaj ID 6497
zafer on 2012-07-05, 01:11:
invariant() bloğunda kullandığım assert() ifadesinde aşağıdaki yazımı bir türlü çalıştıramadım.

assert(konum < yigin.length);

Bunun nedeni birisinin işaretli diğerinin işaretsiz tür olması. Altın ve pis kural: İfadenin içinde bir işaretsiz tür olduğunda bütün ifade işaretsiz olur. :) O yüzden int iken -1 olan konum ifade size_t olduğunda size_t.max olarak kullanılıyor.

Şuradaki "Aritmetik Dönüşümler" başlığına hızlıca göz atmanı öneririm:

  http://ddili.org/ders/d/tur_donusumleri.html

Tabii konum'u size_t yaptıktan sonra artık -1 ile de başlatamazsın çünkü o da size_t.max olarak ilklendirir.

Ek olarak, program size_t'nin 64 bitlik ortamda 64 bit olması nedeniyle bende derlenmedi.

    bool empty() const

dmd programlarını -property seçeneği ile derlemeni öneririm. (Ve -w ile de.) Öyle yapınca yukarıdaki işlevin (ve front()'un da) @property olarak işaretlenmiş olması gerektiğini söylüyor. Çünkü aslında foreach onları parantezsiz olarak çağırıyor.

Ali
acehreli (Moderatör) #29
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Yanıtlanan mesaj #21
Salih Dinçer on 2012-07-05, 13:48:
64 bit sistemde ve emin olmak niyetiyle "-m64 -release" parametreleri ile derledim ve binary dosya çalıştırılamadı.

64 bitlik dmd ile derleyince bir sorun yok. (32 bitlik dmd ile denemedim.)

Ali
zafer #30
Üye Tem 2009 tarihinden beri · 700 mesaj · Konum: Ankara
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Yanıtlanan mesaj #28
acehreli on 2012-07-07, 05:44:
dmd programlarını -property seçeneği ile derlemeni öneririm.

Ali, property bilgisi için teşekkürler ama benim gerçekte ögrenmek istedigim empty() metodunu dış dünyaya nasıl kapatabilirim. Yani empty() aralık işlemlerini gerçeklemek için gerekiyor. Bundan dolayı empty()'nin sadece bu gerçeklemede kullanılması gerektigini ve dışarıdan kontrolsüz erişime kapalı olması gerektigini düşünüyorum. Konuya yanlış bir açıdan mı bakıyorum yoksa?
https://github.com/zafer06 - depo
Doğrulama Kodu: VeriCode Lütfen resimde gördüğünüz doğrulama kodunu girin:
İfadeler: :-) ;-) :-D :-p :blush: :cool: :rolleyes: :huh: :-/ <_< :-( :'( :#: :scared: 8-( :nuts: :-O
Özel Karakterler:
Sayfa:  önceki  1  2  3  4  sonraki 
Forum: Ders Arası RSS
Bağlı değilsiniz. · Şifremi unuttum · ÜYELİK
This board is powered by the Unclassified NewsBoard software, 20100516-dev, © 2003-10 by Yves Goergen
Şu an: 2017-11-21, 19:30:36 (UTC -08:00)