class compressor { public: virtual void compress(void* data)=0; virtual void uncompress(void* data)=0; virtual void status()const=0; }; class rar_compressor : public compressor {...}; class zip_compressor : public compressor {...}; void do_compress(compressor* c, void* in_data, void* out_data) { c->compress(in_data); c->uncompress(out_data); c->status(); }
template<typename Cmp> void do_compress(Cmp& c, void* in_data, void* out_data) { c.compress(in_data); c.uncompress(out_data); c.status(); }
#compressor_interface.h typedef struct compressor_t { // `public` interface void (*compress)(struct compressor_t*, void* data); void (*uncompress)(struct compressor_t*, void* data); void (*status)(struct compressor_t*); // `private` part void* impl_; } compressor_t;
#rar.h void rar_init(compressor_t* c, int cr); void rar_free(compressor_t* c);
#rar.c typedef struct { int compressed_ratio; int error; int time_to_finish; } rar_impl_t; //////////////////////////////////////////////////////////////////////////////// // #define PREPARE_IMPL(c) \ assert(c); \ assert(c->impl_); \ rar_impl_t* impl = (rar_impl_t*)c->impl_; //////////////////////////////////////////////////////////////////////////////// static void compress(compressor_t* c, void* data) { PREPARE_IMPL(c) printf("RAR: compressor working. Compressed ratio: %d\n", impl->compressed_ratio); } //////////////////////////////////////////////////////////////////////////////// static void uncompress(compressor_t* c, void* data) { PREPARE_IMPL(c) printf("RAR: uncompressor working. Will be finished in %d.\n", impl->time_to_finish); } //////////////////////////////////////////////////////////////////////////////// static void status(compressor_t* c) { PREPARE_IMPL(c) printf("Compressed ratio: %d, error: %d\n", impl->compressed_ratio, impl->error); } //////////////////////////////////////////////////////////////////////////////// // void rar_init(compressor_t* c, int cr) { assert(c); c->impl_ = malloc(sizeof(rar_impl_t)); rar_impl_t* impl = (rar_impl_t*)c->impl_; // `private` impl->time_to_finish = 5; impl->compressed_ratio = cr; impl->error = 0; // `public` c->compress = &compress; c->uncompress = &uncompress; c->status = &status; } //////////////////////////////////////////////////////////////////////////////// // void rar_free(compressor_t* c) { PREPARE_IMPL(c) free(impl); }
void work(compressor_t* c, void* data_to_compress, void* data_to_decompress) { c->compress(c, data_to_compress); c->uncompress(c, data_to_decompress); c->status(c); } int main() { void* uncompressed_data[DATA_SIZE]; void* compressed_data[DATA_SIZE]; compressor_t rar; rar_init(&rar, COMP_RATIO); work(&rar, uncompressed_data, compressed_data); rar_free(&rar); printf("\n"); compressor_t zip; zip_init(&zip, VOLUMES); work(&zip, uncompressed_data, compressed_data); zip_free(&zip); return 0; }
typedef struct logging_compressor_t { union { struct compressor_t; struct compressor_t base; }; void (*log)(struct logging_compressor_t* lc); void *impl_; // } logging_compressor_t;
logging_compressor_t lc; lc.compress(...)
lc.base.compress(...)
work(&lc.base, uncompressed_data, compressed_data);
Source: https://habr.com/ru/post/205570/
All Articles