Thread: Like templates in C++, but not really

  1. #1
    Registered User
    Join Date
    Jan 2020
    Posts
    7

    Like templates in C++, but not really

    I have some code that I need to duplicate for several structs, and I don't want to manually copy/paste, then search and replace the words.

    I have a container object, a struct scene, which holds arrays of triangles, spheres and quadrilaterals.
    Code:
    scene.triangles
    And it keeps count of how many triangles there are like this:
    Code:
    scene.triangleCount
    Now you could replace triangle with sphere or quad.
    I have a function that removes a triangle or a sphere or a quad from a scene. It does this by finding the index of the array associated with the provided pointer, then moving the last item in that array to the index, then freeing the pointer, then finally decrementing the count.

    You can search/replace "@TYPE@" for "triangle", "quad", "sphere". Is there a compiler macro or a pragma which does this automatically so I don't have to copy/paste?

    Code:
    static inline void remove@TYPE@(struct scene * scene, struct @TYPE@ * object){
        lockScene(scene); // multiprocessing concerns
        for (unsigned int i = 0; i < scene->@TYPE@Count; ++i){
            if (scene->@TYPE@s[i] == object){
    
                scene->@TYPE@s[i] = scene->@TYPE@s[scene->@TYPE@Count-1];
                scene->@TYPE@s[scene->@TYPE@Count-1] = NULL;
                scene->@TYPE@Count--;
    
                unlockScene(scene); // multip again
    
                free(object->mat);
                free(object);
                return;
            }
        }
    
        assert(1==0); // if we ended up here we failed to find it, crash program
    }

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    Like this perhaps.
    Code:
    #define STR(x)    #x
    #define CAT(x,y)  x ## y
    
    #define STRUCT_REMOVE(x) static void CAT(remove,x) ( struct scene *scene, struct x *object ) { \
       printf("This is " STR(x) "\n"); \
    }
    
    STRUCT_REMOVE(circle)
    STRUCT_REMOVE(line)
    
    int main(void)
    {
    }
    Which expands to
    Code:
    static void removecircle ( struct scene *scene, struct circle *object ) { printf("This is " "circle" "\n"); }
    static void removeline ( struct scene *scene, struct line *object ) { printf("This is " "line" "\n"); }
    
    int main(void)
    {
    }
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Jan 2020
    Posts
    7
    That's a very awesome trick, thanks! I should really pick up a book about #defines...

    For those interested, heres my code now (structs have been typedef'ed, as well as some other minor tweaks):

    Code:
    #define STR(x)    #x     // insert x as a string
    #define CAT(x,y)  x ## y // concatenate x and y in-file as if typed
    #define STRUCT_REMOVE(x) int CAT(remove,x) ( scene *s, x *object ) { \
        /* remove a (x) from a scene */\
        /* prevent scene from being modified by other threads */\
        writeScene(s);\
        \
        /*find the index in the array of our pointer */\
        for (unsigned int i = 0; i < s->CAT(x,Count); ++i)\
            {\
            if (s->CAT(x,s)[i] == object)\
            {\
                /* prevent fragmentation:
                // move last item in the array to this now vacant spot
                // incase object _is_ the last item, this is a waste of time but it
                // doesn't mess anything up so I won't add a branch for dealing with it.*/\
                s->CAT(x,s)[i] = s->CAT(x,s)[s->CAT(x,Count)-1];\
                s->CAT(x,s)[s->CAT(x,Count)-1] = NULL;\
                s->CAT(x,Count)--;\
                \
                /* other threads are free to go at it */\
                doneWritingScene(s);\
                \
                /* only free surface material if it's only being used by (x) */\
                if(object->mat->users==1){\
                    free(object->mat);\
                }\
                free(object);\
                printf("Removed a "STR(x)"\n!");\
                return 1;\
            }\
        }\
        doneWritingScene(s);\
        return -1;\
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Templates and Templates objects
    By Dave11 in forum C++ Programming
    Replies: 6
    Last Post: 07-05-2014, 06:27 AM
  2. Templates...
    By tennisstar in forum C++ Programming
    Replies: 1
    Last Post: 11-14-2012, 10:19 AM
  3. How to use templates on this.
    By m3rk in forum C++ Programming
    Replies: 9
    Last Post: 08-19-2009, 06:15 PM
  4. templates
    By black_spot1984 in forum C++ Programming
    Replies: 6
    Last Post: 11-01-2008, 11:49 PM
  5. When and when not to use templates
    By *ClownPimp* in forum C++ Programming
    Replies: 7
    Last Post: 07-20-2003, 09:36 AM

Tags for this Thread