将std::set“封装”为C库函数,欢迎指正。
/*** cSet.h: CSET接口文件 **************************************************/
#ifndef CSET_API_HEADER
#define CSET_API_HEADER
#ifdef CSET_EXPORT
#define CSET_API extern "C"
#else
#define CSET_API extern
#endif
typedef void* CSET_HANDLE;
typedef void* CSET_ELEMENT;
typedef const void* CSET_CELEMENT;
typedef int BOOL;
typedef BOOL (*CSET_COMPARE)(const CSET_CELEMENT,const CSET_CELEMENT);
typedef void* CSET_ITERATOR;
/***************** 创建、销毁集合 *******************************************/
CSET_API CSET_HANDLE CSET_create(int nElementSize,CSET_COMPARE);
CSET_API void CSET_destroy(CSET_HANDLE);
/***************** 集合属性 ***********************************************/
CSET_API int CSET_size(CSET_HANDLE);
CSET_API BOOL CSET_empty(CSET_HANDLE);
/***************** 创建、销毁迭代器 ***************************************/
CSET_API CSET_ITERATOR CSET_iterator_clone(CSET_ITERATOR);
CSET_API CSET_ITERATOR CSET_begin(CSET_HANDLE);
CSET_API CSET_ITERATOR CSET_end(CSET_HANDLE);
CSET_API CSET_ITERATOR CSET_find(CSET_HANDLE,CSET_CELEMENT);
CSET_API void CSET_destroy_iterator(CSET_ITERATOR);
/***************** 遍历 ***************************************************/
CSET_API void CSET_iterator_next(CSET_ITERATOR);
CSET_API BOOL CSET_iterator_equal(CSET_ITERATOR,CSET_ITERATOR);
CSET_API CSET_ELEMENT CSET_iterator_get(CSET_ITERATOR);
/***************** 添加、删除元素 *******************************************/
CSET_API void CSET_clear(CSET_HANDLE);
CSET_API void CSET_erase(CSET_HANDLE,CSET_ITERATOR);
CSET_API void CSET_erase_range(CSET_HANDLE,CSET_ITERATOR,CSET_ITERATOR);
CSET_API void CSET_insert(CSET_HANDLE,CSET_CELEMENT);
#endif
// cSet.cpp : CSET实现文件
//
#include "cSet.h"
#include <set>
#include <vector>
using namespace std;
typedef vector<char> private_element;
struct comp_wrapper
{
CSET_COMPARE _comp;
comp_wrapper(CSET_COMPARE comp):_comp(comp){};
bool operator()(const private_element& l,const private_element& r)const
{ return _comp(&l[0],&r[0])?true:false; };
};
typedef set<private_element,comp_wrapper> private_set;
struct cset
{
cset(int s,comp_wrapper c):element_size_(s),set_(c){};
int element_size_;
private_set set_;
};
CSET_API CSET_HANDLE CSET_create(int nElementSize,CSET_COMPARE comp)
{
return new cset(nElementSize,comp);
}
CSET_API void CSET_destroy(CSET_HANDLE h)
{
delete static_cast<cset*>(h);
}
CSET_API int CSET_size(CSET_HANDLE h)
{
return static_cast<cset*>(h)->set_.size();
}
CSET_API BOOL CSET_empty(CSET_HANDLE h)
{
return static_cast<cset*>(h)->set_.empty();
}
CSET_API void CSET_erase(CSET_HANDLE h,CSET_ITERATOR it)
{
static_cast<cset*>(h)->set_.erase(*static_cast<private_set::iterator*>(it));
}
CSET_API void CSET_erase_range(CSET_HANDLE h,CSET_ITERATOR l,CSET_ITERATOR r)
{
static_cast<cset*>(h)->set_.erase(*static_cast<private_set::iterator*>(l),
*static_cast<private_set::iterator*>(r));
}
CSET_API CSET_ITERATOR CSET_begin(CSET_HANDLE h)
{
return new private_set::iterator(static_cast<cset*>(h)->set_.begin());
}
CSET_API CSET_ITERATOR CSET_end(CSET_HANDLE h)
{
return new private_set::iterator(static_cast<cset*>(h)->set_.end());
}
CSET_API void CSET_insert(CSET_HANDLE h,CSET_CELEMENT e)
{
private_element element(static_cast<cset*>(h)->element_size_);
memcpy(&element[0],e,static_cast<cset*>(h)->element_size_);
static_cast<cset*>(h)->set_.insert(element);
}
CSET_API CSET_ITERATOR CSET_find(CSET_HANDLE h ,CSET_CELEMENT e)
{
private_element element(static_cast<cset*>(h)->element_size_);
memcpy(&element[0],e,static_cast<cset*>(h)->element_size_);
return new private_set::iterator(static_cast<cset*>(h)->set_.find(element));
}
CSET_API void CSET_destroy_iterator(CSET_ITERATOR it)
{
delete static_cast<private_set::iterator*>(it);
}
CSET_API BOOL CSET_iterator_equal(CSET_ITERATOR l,CSET_ITERATOR r)
{
return *static_cast<private_set::iterator*>(l) ==
*static_cast<private_set::iterator*>(r);
}
CSET_API void CSET_iterator_next(CSET_ITERATOR it)
{
static_cast<private_set::iterator*>(it)->operator++();
}
CSET_API CSET_ITERATOR CSET_iterator_clone(CSET_ITERATOR it)
{
return new private_set::iterator(*static_cast<private_set::iterator*>(it));
}
CSET_API CSET_ELEMENT CSET_iterator_get(CSET_ITERATOR it)
{
return &((*(*static_cast<private_set::iterator*>(it)))[0]);
}
CSET_API void CSET_clear(CSET_HANDLE h)
{
static_cast<cset*>(h)->set_.clear();
}
/*************** sample.c: 示例文件 *******************************/
#include "cSet.h"
#include <stdio.h>
#include <string.h>
struct record{
char name[64];
unsigned int age;
};
BOOL less(const CSET_CELEMENT l,const CSET_CELEMENT r)
{
int result = strcmp(((struct record*)l)->name,((struct record*)r)->name);
if(result==0)
return ((struct record*)l)->age < ((struct record*)r)->age;
return result < 0;
}
void display_record(struct record* lpRecord)
{
printf("%s\t%d\n",lpRecord->name,lpRecord->age);
}
void display(CSET_HANDLE h)
{
CSET_ITERATOR end,it;
end = CSET_end(h);
printf("size:%d empty:%s\n",CSET_size(h),CSET_empty(h)?"true":"false");
for(it=CSET_begin(h);!CSET_iterator_equal(it,end);CSET_iterator_next(it))
display_record((struct record*)CSET_iterator_get(it));
CSET_destroy_iterator(end);
CSET_destroy_iterator(it);
printf("\n");
}
void find(CSET_HANDLE h,struct record* lpRecord)
{
CSET_ITERATOR end = CSET_end(h);
CSET_ITERATOR it = CSET_find(h,lpRecord);
if(!CSET_iterator_equal(it,end))
{
printf("\nfind result:\n");
display_record((struct record*)CSET_iterator_get(it));
}
else
printf("record not found\n");
printf("\n");
CSET_destroy_iterator(it);
CSET_destroy_iterator(end);
}
int main(int argc, char* argv[])
{
struct record element[]={
{"Bill Kempf",30},
{"Patrick Tennberg",28},
{"Tomer Abramson",50},
{"Randy Meyers",16},
{"Patrick Tennberg",90}
};
CSET_HANDLE h;
int cout=sizeof(element)/sizeof(struct record);
CSET_ITERATOR it=NULL,it0=NULL,it1=NULL;
struct record* lpRecord=NULL;
h = CSET_create(sizeof(struct record),less);
while(cout--)
CSET_insert(h,element+cout);
display(h);
find(h,element);
printf("erase element 0 \n");
CSET_erase(h,it=CSET_find(h,element));
display(h);
printf("erase range 2-3 \n");
CSET_iterator_next(it1=CSET_find(h,element+2));
CSET_erase_range(h,it0=CSET_find(h,element+3),it1);
display(h);
printf("clear set\n");
CSET_clear(h);
display(h);
CSET_destroy_iterator(it);
CSET_destroy_iterator(it0);
CSET_destroy_iterator(it1);
CSET_destroy(h);
return 0;
}
Output:
size:5 empty:false
Bill Kempf 30
Patrick Tennberg 28
Patrick Tennberg 90
Randy Meyers 16
Tomer Abramson 50
find result:
Bill Kempf 30
erase element 0
size:4 empty:false
Patrick Tennberg 28
Patrick Tennberg 90
Randy Meyers 16
Tomer Abramson 50
erase range 2-3
size:2 empty:false
Patrick Tennberg 28
Patrick Tennberg 90
clear set
size:0 empty:true