LINUX.ORG.RU

История изменений

Исправление Gyros, (текущая версия) :

У меня есть generic-контейнеры: динамич. массив, список, бин. дерево.

Они хранят не void* data, а TYPE item или TYPE data[] или TYPE *array

Это косплей шаблонов C++.

У них есть ф-ция container_print(FILE* out, CONTAINER *c).

Вот она и вызывает универс. вывод.

Это находится внутри файла с реализ. контейнера. Один раз сделал и забыл. И не лазиешь туда.

По умолчанию контейнер должен иметь такую ф-цию и, след-но, должен быть какой-то формат вывода (не универсальный, а конкретный, например %6.3f для членов float).

Если нужно вывести как-то по другому, то исп. container_get(CONTAINER* c, const size_t index) для доступа в элементам контейнера.

Реализован универс. вывод через проксирующие ф-ции.

Таким обр., для нового типа в контейнере мне надо только написать новую ф-цию

static void fprintf_NEW_TYPE(FILE *output, const NEW_TYPE nt)
{
    fprintf(output,  " конкретный формат ", что-то конкретное);
}

и вставить в

#define FPRINT(output, x)\
  _Generic( (x),\
     unsigned char       : fprintf_byte,  \
     int                 : fprintf_int,   \
     long                : fprintf_long,  \
     float               : fprintf_float, \
     double              : fprintf_double,\
    struct POINT2        : fprintf_pt2,   \
    struct NEW_TYPE      : fprintf_NEW_TYPE\
)(output, x)

Так вот, я попробовал выводить не через прокс. ф-ции, а используя макрос PFMT. Корректно не работало (с float).

Вот я и замутил тему. Теперь разобрался и этот вариант останется теоретическим,. А исп. буду как раньше прокси-ф-ции.

Вот для чего все это.

А вы как свои (или не свои) контейнеры организовываете?

PS Не совсем понял про какой слой

то зачем нужен еще один дополнительный слой?

Исправление Gyros, :

У меня есть generic-контейнеры: динамич. массив, список, бин. дерево.

Они хранят не void* data, а TYPE item или TYPE data[] или TYPE *array

У них есть ф-ция container_print(FILE* out, CONTAINER *c).

Вот она и вызывает универс. вывод.

Это находится внутри файла с реализ. контейнера. Один раз сделал и забыл. И не лазиешь туда.

По умолчанию контейнер должен иметь такую ф-цию и, след-но, должен быть какой-то формат вывода (не универсальный, а конкретный, например %6.3f для членов float).

Если нужно вывести как-то по другому, то исп. container_get(CONTAINER* c, const size_t index) для доступа в элементам контейнера.

Реализован универс. вывод через проксирующие ф-ции.

Таким обр., для нового типа в контейнере мне надо только написать новую ф-цию

static void fprintf_NEW_TYPE(FILE *output, const NEW_TYPE nt)
{
    fprintf(output,  " конкретный формат ", что-то конкретное);
}

и вставить в

#define FPRINT(output, x)\
  _Generic( (x),\
     unsigned char       : fprintf_byte,  \
     int                 : fprintf_int,   \
     long                : fprintf_long,  \
     float               : fprintf_float, \
     double              : fprintf_double,\
    struct POINT2        : fprintf_pt2,   \
    struct NEW_TYPE      : fprintf_NEW_TYPE\
)(output, x)

Так вот, я попробовал выводить не через прокс. ф-ции, а используя макрос PFMT. Корректно не работало (с float).

Вот я и замутил тему. Теперь разобрался и этот вариант останется теоретическим,. А исп. буду как раньше прокси-ф-ции.

Вот для чего все это.

А вы как свои (или не свои) контейнеры организовываете?

PS Не совсем понял про какой слой

то зачем нужен еще один дополнительный слой?

Исправление Gyros, :

У меня есть generic-контейнеры: динамич. массив, список, бин. дерево.

Они хранят не void* data, а TYPE item или TYPE data[] или TYPE *array

У них есть ф-ция container_print(FILE* out, CONTAINER *c).

Вот она и вызывает универс. вывод.

Это находится внутри файла с реализ. контейнера. Один раз сделал и забыл. И не лазиешь туда.

По умолчанию контейнер должен иметь такую ф-цию и, след-но, должен быть какой-то формат вывода (не универсальный, а конкретный, например %6.3f для членов float).

Если нужно вывести как-то по другому, то исп. container_get(CONTAINER* c, const size_t index) для доступа в элементам контейнера.

Реализован универс. вывод через проксирующие ф-ции.

Таким обр., для нового типа в контейнере мне надо только написать новую ф-цию

static void fprintf_NEW_TYPE(FILE *output, const NEW_TYPE nt)
{
    fprintf(output,  " конкретный формат ", что-то конкретное);
}

и вставить в

#define FPRINT(output, x)\
  _Generic( (x),\
     unsigned char       : fprintf_byte,  \
     int                 : fprintf_int,   \
     long                : fprintf_long,  \
     float               : fprintf_float, \
     double              : fprintf_double,\
    struct POINT2        : fprintf_pt2,   \
    struct NEW_TYPE      : fprintf_NEW_TYPE\
)(output, x)

Так вот, я попробовал выводить не через прокс. ф-ции, а используя макрос PFMT. Корректно не работало (с float).

Вот я и замутил тему. Теперь разобрался и этот вариант останется теоретическим,. А исп. буду как раньше прокси-ф-ции.

Вот для чего все это.

А вы как свои (или не свои) контейнеры организовываете?

Исправление Gyros, :

У меня есть generic-контейнеры: динамич. массив, список, бин. дерево.

Они хранят не void* data, а TYPE item или TYPE data[] или TYPE *array

У них есть ф-ция container_print(FILE* out, CONTAINER *c).

Вот она и вызывает универс. вывод.

Это находится внутри файла с реализ. контейнера. Один раз сделал и забыл. И не лазиешь туда.

По умолчанию контейнер должен иметь такую ф-цию и, след-но, должен быть какой-то формат вывода (не универсальный, а конкретный, например %6.3f для членов float).

Если нужно вывести как-то по другому, то исп. container_get(CONTAINER* c, const size_t index) для доступа в элементам контейнера.

Реализован универс. вывод через проксирующие ф-ции.

Таким обр., для нового типа в контейнере мне надо только написать новую ф-цию

static void fprintf_NEW_TYPE(FILE *output, const NEW_TYPE nt)
{
    fprintf(output,  " конкретный формат ", что-то конкретное);
}

и вставить в

#define FPRINT(output, x)\
  _Generic( (x),\
     unsigned char       : fprintf_byte,  \
     int                 : fprintf_int,   \
     long                : fprintf_long,  \
     float               : fprintf_float, \
     double              : fprintf_double,\
    struct POINT2        : fprintf_pt2,   \
    struct NEW_TYPE      : fprintf_NEW_TYPE\
)(output, x)

Так вот, я попробовал выводить не через прокс. ф-ции, а используя макрос PFMT. Корректно не работало (с float).

Вот я и замутил тему. Теперь разобрался и этот вариант останется теоретическим,. А исп. буду как раньше прокси-ф-ции.

Вот для чего все это.

Исправление Gyros, :

У меня есть generic-контейнеры: динамич. массив, список, бин. дерево.

Они хранят не void* data, а TYPE item или TYPE data[] или TYPE *array

У них есть ф-ция container_print(FILE* out, CONTAINER *c).

Вот она и вызывает универс. вывод.

Это находится внутри файла с реализ. контейнера. Один раз сделал и забыл. И не лазиешь туда.

По умолчанию контейнер должен иметь такую ф-цию и, след-но, должен быть какой-то формат вывода (не универсальный, а конкретный, например %6.3f для членов float).

Если нужно вывести как-то по другому, то исп. container_get(CONTAINER* c, const size_t index) для доступа в элементам контейнера.

Реализован универс. вывод через проксирующие ф-ции.

Таким обр., для нового типа в контейнере мне надо только написать др ф-цию

static void fprintf_NEW_TYPE(FILE *output, const NEW_TYPE nt)
{
    fprintf(output,  " конкретный формат ", что-то конкретное);
}

и вставить в

#define FPRINT(output, x)\
  _Generic( (x),\
     unsigned char       : fprintf_byte,  \
     int                 : fprintf_int,   \
     long                : fprintf_long,  \
     float               : fprintf_float, \
     double              : fprintf_double,\
    struct POINT2        : fprintf_pt2,   \
    struct NEW_TYPE      : fprintf_NEW_TYPE\
)(output, x)

Так вот, я попробовал выводить не через прокс. ф-ции, а используя макрос PFMT. Корректно не работало (с float).

Вот я и замутил тему. Теперь разобрался и этот вариант останется теоретическим,. А исп. буду как раньше прокси-ф-ции.

Вот для чего все это.

Исправление Gyros, :

У меня есть generic-контейнеры: динамич. массив, список, бин. дерево.

Они хранят не void* data, а TYPE data или TYPE data[] или TYPE *array

У них есть ф-ция container_print(FILE* out, CONTAINER *c).

Вот она и вызывает универс. вывод.

Это находится внутри файла с реализ. контейнера. Один раз сделал и забыл. И не лазиешь туда.

По умолчанию контейнер должен иметь такую ф-цию и, след-но, должен быть какой-то формат вывода (не универсальный, а конкретный, например %6.3f для членов float).

Если нужно вывести как-то по другому, то исп. container_get(CONTAINER* c, const size_t index) для доступа в элементам контейнера.

Реализован универс. вывод через проксирующие ф-ции.

Таким обр., для нового типа в контейнере мне надо только написать др ф-цию

static void fprintf_NEW_TYPE(FILE *output, const NEW_TYPE nt)
{
    fprintf(output,  " конкретный формат ", что-то конкретное);
}

и вставить в

#define FPRINT(output, x)\
  _Generic( (x),\
     unsigned char       : fprintf_byte,  \
     int                 : fprintf_int,   \
     long                : fprintf_long,  \
     float               : fprintf_float, \
     double              : fprintf_double,\
    struct POINT2        : fprintf_pt2,   \
    struct NEW_TYPE      : fprintf_NEW_TYPE\
)(output, x)

Так вот, я попробовал выводить не через прокс. ф-ции, а используя макрос PFMT. Корректно не работало (с float).

Вот я и замутил тему. Теперь разобрался и этот вариант останется теоретическим,. А исп. буду как раньше прокси-ф-ции.

Вот для чего все это.

Исправление Gyros, :

У меня есть generic-контейнеры: динамич. массив, список, бин. дерево.

Они хранят не void* data,а TYPE data или TYPE data[]

У них есть ф-ция container_print(FILE* out, CONTAINER *c).

Вот она и вызывает универс. вывод.

Это находится внутри файла с реализ. контейнера. Один раз сделал и забыл. И не лазиешь туда.

По умолчанию контейнер должен иметь такую ф-цию и, след-но, должен быть какой-то формат вывода (не универсальный, а конкретный, например %6.3f для членов float).

Если нужно вывести как-то по другому, то исп. container_get(CONTAINER* c, const size_t index) для доступа в элементам контейнера.

Реализован универс. вывод через проксирующие ф-ции.

Таким обр., для нового типа в контейнере мне надо только написать др ф-цию

static void fprintf_NEW_TYPE(FILE *output, const NEW_TYPE nt)
{
    fprintf(output,  " конкретный формат ", что-то конкретное);
}

и вставить в

#define FPRINT(output, x)\
  _Generic( (x),\
     unsigned char       : fprintf_byte,  \
     int                 : fprintf_int,   \
     long                : fprintf_long,  \
     float               : fprintf_float, \
     double              : fprintf_double,\
    struct POINT2        : fprintf_pt2,   \
    struct NEW_TYPE      : fprintf_NEW_TYPE\
)(output, x)

Так вот, я попробовал выводить не через прокс. ф-ции, а используя макрос PFMT. Корректно не работало (с float).

Вот я и замутил тему. Теперь разобрался и этот вариант останется теоретическим,. А исп. буду как раньше прокси-ф-ции.

Вот для чего все это.

Исправление Gyros, :

У меня есть generic-контейнеры: динамич. массив, список, бин. дерево.

У них есть ф-ция container_print(FILE* out, CONTAINER *c).

Вот она и вызывает универс. вывод.

Это находится внутри файла с реализ. контейнера. Один раз сделал и забыл. И не лазиешь туда.

По умолчанию контейнер должен иметь такую ф-цию и, след-но, должен быть какой-то формат вывода (не универсальный, а конкретный, например %6.3f для членов float).

Если нужно вывести как-то по другому, то исп. container_get(CONTAINER* c, const size_t index) для доступа в элементам контейнера.

Реализован универс. вывод через проксирующие ф-ции.

Таким обр., для нового типа в контейнере мне надо только написать др ф-цию

static void fprintf_NEW_TYPE(FILE *output, const NEW_TYPE nt)
{
    fprintf(output,  " конкретный формат ", что-то конкретное);
}

и вставить в

#define FPRINT(output, x)\
  _Generic( (x),\
     unsigned char       : fprintf_byte,  \
     int                 : fprintf_int,   \
     long                : fprintf_long,  \
     float               : fprintf_float, \
     double              : fprintf_double,\
    struct POINT2        : fprintf_pt2,   \
    struct NEW_TYPE      : fprintf_NEW_TYPE\
)(output, x)

Так вот, я попробовал выводить не через прокс. ф-ции, а используя макрос PFMT. Корректно не работало (с float).

Вот я и замутил тему. Теперь разобрался и этот вариант останется теоретическим,. А исп. буду как раньше прокси-ф-ции.

Вот для чего все это.

Исправление Gyros, :

У меня есть generic-контейнеры: динамич. массив, список, бин. дерево.

У них есть ф-ция container_print(FILE* out, CONTAINER *c).

Вот она и вызывает универс. вывод.

Это находится внутри файла с реализ. контейнера. Один раз сделал и забыл. И не лазиешь туда.

По умолчанию контейнер должен иметь такую ф-цию и, след-но, должен быть какой-то формат вывода (не универсальный, а конкретный, например %6.3f для членов float).

Если нужно вывести как-то по другому, то исп. container_get(CONTAINER* c, const size_t index) для доступа в элементам контейнера.

Реализован универс. вывод через проксирующие ф-ции.

Таким обр., для нового типа в контейнере мне надо только написать др ф-цию

static void fprintf_NEW_TYPE(FILE *output, const NEW_TYPE nt)
{
    fprintf(output,  " конкретный формат ", что-то конкретное);
}

и вставить в

#define FPRINT(output, x)\
  _Generic( (x),\
     unsigned char       : fprintf_byte,  \
     int                 : fprintf_int,   \
     long                : fprintf_long,  \
     float               : fprintf_float, \
     double              : fprintf_double,\
    struct POINT2        : fprintf_pt2,   \
    NEW_TYPE             : fprintf_NEW_TYPE\
)(output, x)

Так вот, я попробовал выводить не через прокс. ф-ции, а используя макрос PFMT. Корректно не работало (с float).

Вот я и замутил тему. Теперь разобрался и этот вариант останется теоретическим,. А исп. буду как раньше прокси-ф-ции.

Вот для чего все это.

Исходная версия Gyros, :

У меня есть generic-контейнеры: динамич. массив, список, бин. дерево.

У них есть ф-ция container_print(FILE* out, CONTAINER *c).

Вот она и вызывает универс. вывод.

Это находится внутри файла с реализ. контейнера. Один раз сделал и забыл. И не лазиешь туда.

По умолчанию контейнер должен иметь такую ф-цию и, след-но, должен быть какой-то формат вывода (не универсальный, а конкретный, например %6.3f для членов float).

Если нужно вывести как-то по другому, то исп. container_get(CONTAINER* c, const size_t index) для доступа в элементам контейнера.

Реализован универс. вывод через проксирующие ф-ции.

Таким обр., для нового типа в контейнере мне надо только написать др ф-цию

static void fprintf_NEW_TYPE(FILE *output, const NEW_TYPW nt)
{
    fprintf(output,  " конкретный формат ", что-то конкретное);
}

и вставить в

#define FPRINT(output, x)\
  _Generic( (x),\
     unsigned char       : fprintf_byte,  \
     int                 : fprintf_int,   \
     long                : fprintf_long,  \
     float               : fprintf_float, \
     double              : fprintf_double,\
    struct POINT2        : fprintf_pt2,   \
    NEW_TYPE             : fprintf_NEW_TYPE\
)(output, x)

Так вот, я попробовал выводить не через прокс. ф-ции, а используя макрос PFMT. Корректно не работало (с float).

Вот я и замутил тему. Теперь разобрался и этот вариант останется теоретическим,. А исп. буду как раньше прокси-ф-ции.

Вот для чего все это.