GithubHelp home page GithubHelp logo

christianfriedl / cgenerics Goto Github PK

View Code? Open in Web Editor NEW
1.0 1.0 0.0 227 KB

A library for generic programming and OOP in C

License: GNU General Public License v3.0

Perl 0.86% C 89.17% C++ 5.89% Objective-C 2.31% CMake 1.77%

cgenerics's Introduction

CGenerics

A library for generic programming and OOP in C

This is one of my weekend self-education projects. My original intention was to base a BNF parser on this, and then a parser for an actual language on that... Obviously, this never came to fruition. Duh.

The project was to create a library of fundamental generic data structures in pure C. The basic idea was to use macros, especially ## expansion (I forget the technical term), to create a C type from a base name and a type.

For example:

cgArray(Int)* array = cgArray__new(Int, 20);

by way of

cgArrayOf##TYPENAME* cgArrayOf##TYPENAME##__new(const unsigned int initialCapacity);

would expand to

cgArrayOfInt* array = cgArrayOfInt__new(20);

So anyway, here are my learnings, and the principles I was trying to employ in this project:

Design principles and coding style

  • All functions are prefixed with cg.
  • Instance methods have one underscore between class name and method name (<Typename>_doStuff(...)).
  • Static class methods have two underscores between class name and method name (<Typename>__new(...)).
  • "Private" methods have static scope and end on an underscore (end, so vi's/ctag's keyword expansion can find it even if we change the visibility), e.g. static cgAppState *cgAppState__new_(const char *name);
  • Constructors are named <Typename>__new(...).
  • Alternative constructors are named <Typename>__newFrom<Foo>(...).
  • Destructors are named <Typename>__delete()
  • Generic containers have a destructor named <Typename>_deleteValues() which will delete just the contents of the container by calling the corresponding <Typename>_delete() method.
  • For each class there is a header named exactly like this class.
  • For each generic class, there is a set of macros that will expand to declarations and definitions of the basic type and "methods" for that class.
  • cgAppState is a Singleton, thus it has a private constructor and a method cgAppState__getInstance().

Example class: cgArray (defined in src/cgArray.h)

#define DECLARE_ARRAY_TYPE(TYPENAME)

to create the typedef

#define DECLARE_ARRAY_FUNCS(TYPENAME)

to create all the "methods"

#define DECLARE_ARRAY(TYPENAME)

to unify the above two marcos for convenience

#define DEFINE_ARRAY(TYPENAME)

to actually create the function definitions of our "methods"

#define INIT_ARRAY(TYPENAME)

to unify the above two macros for convenience

Takeaways and learnings

  • You can achieve some limited success by way of macros. The major limitation is that macros don't recurse, so you can not do collections of collections (without using some hacks like pre-expanding some part of your headers...)
  • Another limitation is that everything you put into your generics has to be a pointer, so it has to be an object, so you have to have a class definition, a constructor etc. for it (or forsake code uniformity, which is Not A Good Thing).
  • You can not effectively do exceptions in C. I tried it by way of convention (see https://github.com/christianfriedl/CGenerics/blob/master/src/cgAppState.h), but then EVERY method call needs to check for "Exceptions" afterwards, and that is rather unseemly to say the least. The only other way I know would be to change the binary, so essentially write your own compiler.
  • Of course, fundamental algorithms are extremely nasty with regards to edge cases, and you have to be sure you really covered them all. This library does not cover even the most fundamental issues. So in the extremely unlikely case that you intend to use any part of this for any serious business, please use utter caution, because I didn't. You have been warned! (And a pull request would be nice!)
  • I have since come to the True Belief of never using unsigned int, because it only gives you one extra bit, but can get you in an awful lot of trouble if you're not extremely careful.
  • I would be very hesitant about using another singleton. I think it's the most overrated pattern ever.

License

CGenerics is Copyright (c) by Christian Friedl.

The License of CGEnerics is GPLv3. See https://github.com/christianfriedl/CGenerics/blob/master/COPYING

cgenerics's People

Stargazers

Christian Friedl avatar

Watchers

Christian Friedl avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.