fork(2) download
  1. #include <stdio.h>
  2.  
  3. /**
  4.  * Это собственно реализация именованных параметров, пропускаем
  5.  */
  6. #define structer(name, param) typedef struct param name;
  7. #define fname(f) f ## _func
  8. #define sname(f) f ## _stru
  9. #define function_(type, f, argname, param)\
  10. structer(sname(f), param) type fname(f)(sname(f) argname)
  11. #define bind(f, ...) fname(f)((sname(f)) {__VA_ARGS__})
  12.  
  13.  
  14. /**
  15.  * Синтаксис
  16.  * function_(<return_type>, <function_name>, <arg_container_name>, {<arguments>})
  17.  * Объявляешь как обычную функцию, только теперь параметры в её теле
  18.  * попадут в структуру <arg_container_name>
  19.  *
  20.  * Пример ниже: длина вектора.
  21.  * Выглядит стрёмно, но зато потом можно, во-первых, забиндить параметры по умолчанию,
  22.  * а во-вторых, использовать с именованными аргументами (как в питоне)
  23.  */
  24. function_(double, vectorLength, in, {double x; double y; double z;}) {
  25. return sqrt(in.x*in.x + in.y*in.y + in.z*in.z);
  26. }
  27.  
  28. /**
  29.  * Синтаксис
  30.  * #define <new_f_name>(...) bind(<function_name>, <default_values...>, __VA_ARGS__)
  31.  * <function_name> должна быть фукнцией, объявленной способом выше (через function_).
  32.  * <new_f_name> это уже реально используемая фукнция, только параметры ей передаются
  33.  * префиксированные точкой (как записаны <default_values> в примере ниже).
  34.  * В конце нужно обязательно дописывать __VA_ARGS__
  35.  *
  36.  * Пример: взяли vectorLength и переделали в vectorLengthZero, у которого
  37.  * аргументы по умолчанию равны нулю.
  38.  * Второй пример: аргументы по умолчанию делаем равными 3, 0 и 0.
  39.  */
  40. #define vectorLengthZero(...) bind(vectorLength, .x=0, .y=0, .z=0, __VA_ARGS__)
  41. #define vectorLengthOne(...) bind(vectorLength, .x=3, .y=0, .z=0, __VA_ARGS__)
  42.  
  43. int main() {
  44. printf("|(0,0,0)|: %f\n", vectorLengthZero() );
  45. printf("|(1,0,0)|: %f\n", vectorLengthZero(.x = 1) );
  46. printf("|(0,1,0)|: %f\n", vectorLengthZero(.y = 1) );
  47. printf("|(1,1,0)|: %f\n", vectorLengthZero(.y = 1, .x = 1) );
  48. printf("\n");
  49. printf("|(3,0,0)|: %f\n", vectorLengthOne() );
  50. printf("|(3,0,4)|: %f\n", vectorLengthOne(.z = 4) );
  51. printf("|(12,3,4)|: %f\n", vectorLengthOne(.z = 4, .y = 3, .x = 12) );
  52. return 0;
  53. }
Success #stdin #stdout 0s 2008KB
stdin
Standard input is empty
stdout
|(0,0,0)|: 0.000000
|(1,0,0)|: 1.000000
|(0,1,0)|: 1.000000
|(1,1,0)|: 1.414214

|(3,0,0)|: 3.000000
|(3,0,4)|: 5.000000
|(12,3,4)|: 13.000000