CIRCLEQ(3)

الاسم
CIRCLEQ_EMPTY، CIRCLEQ_ENTRY، CIRCLEQ_FIRST، CIRCLEQ_FOREACH، CIRCLEQ_FOREACH_REVERSE، CIRCLEQ_HEAD، CIRCLEQ_HEAD_INITIALIZER، CIRCLEQ_INIT، CIRCLEQ_INSERT_AFTER، CIRCLEQ_INSERT_BEFORE، CIRCLEQ_INSERT_HEAD، CIRCLEQ_INSERT_TAIL، CIRCLEQ_LAST، CIRCLEQ_LOOP_NEXT، CIRCLEQ_LOOP_PREV، CIRCLEQ_NEXT، CIRCLEQ_PREV، CIRCLEQ_REMOVE - تنفيذ طابور دائري مزدوج الوصل

المكتبة
مكتبة سي المعيارية (libc، -lc)

موجز
#include <sys/queue.h>

CIRCLEQ_ENTRY(TYPE);

CIRCLEQ_HEAD(HEADNAME, TYPE);
CIRCLEQ_HEAD CIRCLEQ_HEAD_INITIALIZER(CIRCLEQ_HEAD head);
void CIRCLEQ_INIT(CIRCLEQ_HEAD *head);

int CIRCLEQ_EMPTY(CIRCLEQ_HEAD *head);

void CIRCLEQ_INSERT_HEAD(CIRCLEQ_HEAD *head,
                           struct TYPE *elm, CIRCLEQ_ENTRY NAME);
void CIRCLEQ_INSERT_TAIL(CIRCLEQ_HEAD *head,
                           struct TYPE *elm, CIRCLEQ_ENTRY NAME);
void CIRCLEQ_INSERT_BEFORE(CIRCLEQ_HEAD *head, struct TYPE *listelm,
                           struct TYPE *elm, CIRCLEQ_ENTRY NAME);
void CIRCLEQ_INSERT_AFTER(CIRCLEQ_HEAD *head, struct TYPE *listelm,
                           struct TYPE *elm, CIRCLEQ_ENTRY NAME);

struct TYPE *CIRCLEQ_FIRST(CIRCLEQ_HEAD *head);
struct TYPE *CIRCLEQ_LAST(CIRCLEQ_HEAD *head);
struct TYPE *CIRCLEQ_PREV(struct TYPE *elm, CIRCLEQ_ENTRY NAME);
struct TYPE *CIRCLEQ_NEXT(struct TYPE *elm, CIRCLEQ_ENTRY NAME);
struct TYPE *CIRCLEQ_LOOP_PREV(CIRCLEQ_HEAD *head,
                           struct TYPE *elm, CIRCLEQ_ENTRY NAME);
struct TYPE *CIRCLEQ_LOOP_NEXT(CIRCLEQ_HEAD *head,
                           struct TYPE *elm, CIRCLEQ_ENTRY NAME);

CIRCLEQ_FOREACH(struct TYPE *var, CIRCLEQ_HEAD *head,
                           CIRCLEQ_ENTRY NAME);
CIRCLEQ_FOREACH_REVERSE(struct TYPE *var, CIRCLEQ_HEAD *head,
                           CIRCLEQ_ENTRY NAME);

void CIRCLEQ_REMOVE(CIRCLEQ_HEAD *head, struct TYPE *elm,
                           CIRCLEQ_ENTRY NAME);

الوصف
تعرف هذه الكليّات وتُشغّل طوابير دائرية مزدوجة الوصل.

في تعريفات الكليّات، TYPE هو اسم بنية معرّفة من المستخدم، يجب أن تحتوي على حقل من نوع CIRCLEQ_ENTRY، اسمه NAME. الوسيط HEADNAME هو اسم بنية معرّفة من المستخدم يجب أن تُصرّح باستخدام الكلية CIRCLEQ_HEAD().

  الإنشاء
يترأس الطابور الدائري بنية معرّفة بالكلية CIRCLEQ_HEAD(). تحتوي هذه البنية على زوج من المؤشرات، واحد إلى أول عنصر في الطابور والآخر إلى آخر عنصر في الطابور. العناصر موصولة مزدوجًا بحيث يمكن إزالة أي عنصر دون اجتياز الطابور. يمكن إضافة عناصر جديدة إلى الطابور بعد عنصر موجود، قبل عنصر موجود، في رأس الطابور، أو في نهاية الطابور. تُصرّح بنية CIRCLEQ_HEAD كالتالي:

    CIRCLEQ_HEAD(HEADNAME, TYPE) head;

حيث struct HEADNAME هي البنية المراد تعريفها، و struct TYPE هو نوع العناصر المراد ربطها في الطابور. يمكن لاحقًا التصريح عن مؤشر لرأس الطابور كـ:

    struct HEADNAME *headp;

(الاسمان head و headp يمكن للمستخدم اختيارهما.)

CIRCLEQ_ENTRY() تُصرّح ببنية تصل العناصر في الطابور.

CIRCLEQ_HEAD_INITIALIZER() تُقيّم إلى مُهيئ للطابور head.

CIRCLEQ_INIT() تُهيئ الطابور المشار إليه بـ head.

CIRCLEQ_EMPTY() تُقيّم إلى صحيح إذا لم تكن هناك عناصر في الطابور.

  إدراج
CIRCLEQ_INSERT_HEAD() تُدرج العنصر الجديد elm في رأس الطابور.

CIRCLEQ_INSERT_TAIL() تُدرج العنصر الجديد elm في نهاية الطابور.

CIRCLEQ_INSERT_BEFORE() تُدرج العنصر الجديد elm قبل العنصر listelm.

CIRCLEQ_INSERT_AFTER() تُدرج العنصر الجديد elm بعد العنصر listelm.

  اجتياز
CIRCLEQ_FIRST() تُرجع أول عنصر في الطابور.

CIRCLEQ_LAST() تُرجع آخر عنصر في الطابور.

CIRCLEQ_PREV() تُرجع العنصر السابق في الطابور، أو &head إذا كان هذا العنصر هو الأول.

CIRCLEQ_NEXT() تُرجع العنصر التالي في الطابور، أو &head إذا كان هذا العنصر هو الأخير.

CIRCLEQ_LOOP_PREV() تُرجع العنصر السابق في الطابور. إذا كان elm هو العنصر الأول في الطابور، يُرجع العنصر الأخير.

CIRCLEQ_LOOP_NEXT() تُرجع العنصر التالي في الطابور. إذا كان elm هو العنصر الأخير في الطابور، يُرجع العنصر الأول.

CIRCLEQ_FOREACH() تجتاز الطابور المُشار إليه بـ head في الاتجاه الأمامي، مُسندةً كل عنصر بدوره إلى var. يُضبط var إلى &head إذا اكتملت الحلقة بشكل طبيعي، أو إذا لم تكن هناك عناصر.

CIRCLEQ_FOREACH_REVERSE() تجتاز الطابور المُشار إليه بـ head في الاتجاه العكسي، مُسندةً كل عنصر بدوره إلى var.

  إزالة
CIRCLEQ_REMOVE() تُزيل العنصر elm من الطابور.

قيمة الإرجاع
CIRCLEQ_EMPTY() تُرجع قيمة غير صفرية إذا كان الطابور فارغًا، وصفرًا إذا كان الطابور يحتوي على إدخال واحد على الأقل.

CIRCLEQ_FIRST()، CIRCLEQ_LAST()، CIRCLEQ_LOOP_PREV()، و CIRCLEQ_LOOP_NEXT() تُرجع مؤشرًا إلى بنية TYPE الأولى أو الأخيرة أو السابقة أو التالية، على التوالي.

CIRCLEQ_PREV() و CIRCLEQ_NEXT() مماثلتان لنظيرتيهما CIRCLEQ_LOOP_*()، باستثناء أنه إذا كانت الوسيطة هي العنصر الأول أو الأخير، على التوالي، فإنهما تُرجعان &head.

CIRCLEQ_HEAD_INITIALIZER() تُرجع مُهيئًا يمكن إسناده إلى رأس الطابور head.

المعايير
BSD.

العلل
CIRCLEQ_FOREACH() و CIRCLEQ_FOREACH_REVERSE() لا تسمحان بإزالة var أو تحريره داخل الحلقة، لأن ذلك سيتداخل مع الاجتياز. CIRCLEQ_FOREACH_SAFE() و CIRCLEQ_FOREACH_REVERSE_SAFE()، الموجودتان في أنظمة BSD ولكن غير موجودتين في glibc، تُصلحان هذا القيد بالسماح بإزالة var بأمان من القائمة وتحريره من داخل الحلقة دون التداخل مع الاجتياز.

أمثلة
    #include <stddef.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/queue.h>

    struct entry {
        int data;
        CIRCLEQ_ENTRY(entry) entries;           /* Queue */
    };

    CIRCLEQ_HEAD(circlehead, entry);

    int
    main(void)
    {
        struct entry *n1, *n2, *n3, *np;
        struct circlehead head;                 /* Queue head */
        int i;

        CIRCLEQ_INIT(&head);                    /* Initialize the queue */

        n1 = malloc(sizeof(struct entry));      /* Insert at the head */
        CIRCLEQ_INSERT_HEAD(&head, n1, entries);

        n1 = malloc(sizeof(struct entry));      /* Insert at the tail */
        CIRCLEQ_INSERT_TAIL(&head, n1, entries);

        n2 = malloc(sizeof(struct entry));      /* Insert after */
        CIRCLEQ_INSERT_AFTER(&head, n1, n2, entries);

        n3 = malloc(sizeof(struct entry));      /* Insert before */
        CIRCLEQ_INSERT_BEFORE(&head, n2, n3, entries);

        CIRCLEQ_REMOVE(&head, n2, entries);     /* Deletion */
        free(n2);
                                                /* Forward traversal */
        i = 0;
        CIRCLEQ_FOREACH(np, &head, entries)
            np->data = i++;
                                                /* Reverse traversal */
        CIRCLEQ_FOREACH_REVERSE(np, &head, entries)
            printf("%i\n", np->data);
                                                /* Queue deletion */
        n1 = CIRCLEQ_FIRST(&head);
        while (n1 != (void *)&head) {
            n2 = CIRCLEQ_NEXT(n1, entries);
            free(n1);
            n1 = n2;
        }
        CIRCLEQ_INIT(&head);

        exit(EXIT_SUCCESS);
    }

انظر أيضًا
insque(3)، queue(7)

ترجمة
تُرجمت هذه الصفحة من الدليل بواسطة زايد السعيدي <zayed.alsaidi@gmail.com>

هذه الترجمة هي وثيقة مجانية؛ راجع رخصة جنو العامة الإصدار 3 (https://www.gnu.org/licenses/gpl-3.0.html) أو ما بعده للاطلاع على شروط حقوق النشر. لا توجد أي ضمانات.

إذا وجدت أي أخطاء في ترجمة صفحة الدليل هذه، يرجى إرسال بريد إلكتروني إلى قائمة بريد المترجمين: kde-l10n-ar@kde.org.