Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon. Entire thread

Generic programming in C

Name: Anonymous 2012-01-12 3:49

I love C so much, and I really want to hate sepples, but I can't help but think that generic programming in C is shit! Macros are no good for generic data structures, as they are clunky and blow out code size, nor are void pointers, as you need to allocate separate memory just to store an integer (don't stuff ints into pointers; zeros won't work on architectures where the null pointer constant is non-zero). I really want to write my data structure library in sepples, where templates allow type genericism without issue. What should I do, /prague/; what should I do?!

Name: Anonymous 2012-01-12 8:22

>>14

Part 2 of 2:

/**
 * vector_pop
 * Removes and returns the element
 * at the end of the vector.
 *
 * @param  (vector(type) *) vector in question
 * @return (type) the removed element
 */
#define vector_pop(v)                           \
  ({                                            \
    typeof(v) v__ = (v);                        \
                                                \
    v__->head == v__->base ?                    \
      (typeof(*v__->base)) VECTOR_ERROR :       \
      *--v__->head;                             \
  })

/**
 * vector_pop_first
 * Removes and returns the first
 * element of the vector.
 *
 * @param  (vector(type) *) vector in question
 * @return (type) the removed element
 */
#define vector_pop_first(v)                     \
  ({                                            \
    typeof(v) v__ = (v);                        \
    typeof(*v__->base) l__;                     \
    ptrdiff_t size__;                           \
                                                \
    size__ = vector_size(v);                    \
                                                \
    if (size__ > 1) {                           \
      int i__;                                  \
                                                \
      l__ = v__->base[0];                       \
                                                \
      for (i__ = 0; i__ < size__-1; i__++)      \
        v__->base[i__] = v__->base[i__+1];      \
                                                \
      v__->head -= 1;                           \
    } else {                                    \
      l__ = vector_pop(v);                      \
    }                                           \
                                                \
    l__;                                        \
  })

/**
 * vector_prepend
 * Adds element to the front of vector.
 *
 * @param  (vector(type) *) vector in question
 * @param  (type) element to be added to vector
 * @return (type) element that was added
 */
#define vector_prepend(v, e)                    \
  ({                                            \
    typeof(v)          v__ = (v);               \
    typeof(*v__->base) e__ = (e);               \
    typeof(*v__->base) l__;                     \
    ptrdiff_t size__ = vector_size(v);          \
                                                \
    if (size__ > 0) {                           \
      int i__;                                  \
                                                \
      l__ = v__->base[size__-1];                \
                                                \
      for (i__ = size__ - 1; i__ > 0; i__--)    \
        v__->base[i__] = v__->base[i__-1];      \
                                                \
      v__->base[0] = e__;                       \
    } else {                                    \
      l__ = e__;                                \
    }                                           \
                                                \
    vector_append(v, l__) ==                    \
      (typeof(*v__->base)) VECTOR_ERROR ?       \
      (typeof(*v__->base)) VECTOR_ERROR :       \
      e__;                                      \
  })

/**
 * vector_remove
 * Removes and returns an element at a
 * certain position in vector.
 *
 * @param  (vector(type) *) vector in question
 * @param  (int) index of element
 * @param  (type) the removed element
 */
#define vector_remove(v, i)                     \
  ({                                            \
    typeof(v)          v__ = (v);               \
    typeof(*v__->base) l__;                     \
    int i__ = (i);                              \
    ptrdiff_t size__ = vector_size(v);          \
                                                \
    l__ = (typeof(*v__->base)) VECTOR_ERROR;    \
                                                \
    if (i__ < 0)                                \
      l__ = l__;                                \
    else if (i__ == size__-1)                   \
      l__ = vector_pop(v);                      \
    else if (i__ < size__) {                    \
      int j__;                                  \
                                                \
      l__ = v__->base[i__];                     \
                                                \
      for (j__ = i__; j__ < size__-1; j__++)    \
        v__->base[j__] = v__->base[j__+1];      \
                                                \
      v__->head -= 1;                           \
    } else                                      \
      l__ = l__;                                \
                                                \
    l__;                                        \
  })

/**
 * vector_set
 * Sets the element at a certain position
 * in the vector and removes the old element.
 *
 * @param  (vector(type) *) the vector in question
 * @param  (int) index of new element
 * @param  (type) element to be added
 * @return (type) element that was added
 */
#define vector_set(v, i, e)                     \
  ({                                            \
    typeof(v)          v__ = (v);               \
    typeof(*v__->base) e__ = (e);               \
    typeof(*v__->base) l__;                     \
    int i__ = (i);                              \
    ptrdiff_t size__;                           \
                                                \
    size__ = vector_size(v);                    \
    l__ = (typeof(*v__->base)) VECTOR_ERROR;    \
                                                \
    if (i__ < 0)                                \
      l__ = l__;                                \
    else if (i__ < size__)                      \
      l__ = (v__->base[i__] = e__);             \
    else if (i__ == size__)                     \
      l__ = vector_append(v, e);                \
    else                                        \
      l__ = l__;                                \
                                                \
    l__;                                        \
  })

/**
 * vector_size
 * Returns the current number of elements
 * in the vector.
 *
 * @param  (const vector(type) *) vector in question
 * @return (ptrdiff_t) number of elements in vector
 */
#define vector_size(v)                          \
  ({                                            \
    typeof(v) v__   = (v);                      \
                                                \
    v__->head - v__->base;                      \
  })

/**
 * vector_trim
 * Resizes the underlying array so only the
 * elements currently in vector fits.
 *
 * @param  (vector(type) *) the vector in question
 * @return (vector(type) *) the trimmed vector
 */
#define vector_trim(v)                          \
  ({                                            \
    typeof(v) v__ = (v);                        \
    typeof(v__->base) b__;                      \
    ptrdiff_t size__ = vector_size(v);          \
                                                \
    b__ = realloc(v__->base,                    \
                  size__ * sizeof(*v__->base)); \
                                                \
    if (b__ != VECTOR_ERROR) {                  \
      v__->base = b__;                          \
      v__->head = b__ + size__;                 \
      v__->end  = b__ + size__;                 \
    }                                           \
                                                \
    b__ == VECTOR_ERROR ?                       \
      VECTOR_ERROR :                            \
      v__;                                      \
  })

#endif /* VECTOR_H__ */

Newer Posts
Don't change these.
Name: Email:
Entire Thread Thread List