00001
00002 #ifndef AKAXISO2_FRAMEWORK_ARRAY_H__
00003 #define AKAXISO2_FRAMEWORK_ARRAY_H__
00004
00010 #include <akaxiso2/framework/simpletype.h>
00011 #include <akaxiso2/framework/container_methods.h>
00012 #include <akaxiso2/framework/equals.h>
00013
00014 namespace aka2 {
00015
00016 template<class C>
00017 class typed_array_iterator : public array_iterator {
00018 public:
00019 typed_array_iterator(const C& container) :
00020 container_(container), current_(container.begin()) {}
00021 virtual ~typed_array_iterator(){}
00022
00023 const C &container_;
00024 TYPENAME C::const_iterator current_;
00025
00026 virtual bool has_next() const { return current_ != container_.end(); }
00027 virtual const void *next() {
00028 assert(has_next());
00029 const TYPENAME C::value_type &v = *current_;
00030 ++current_;
00031 return &v;
00032 }
00033 };
00034
00035 template<class L, class VL>
00036 class array_op_dispatcher : public array_op {
00037 public:
00038 virtual schematype_id get_schematype() const { return array_id; }
00039 virtual std::string get_typename() const { return L::get_xmltype(); }
00040 virtual const attribute_types *get_attribute_types() const { return 0; }
00041 virtual const attribute_type *get_anyattr_type() const { return 0; }
00042
00043 virtual void construct(void *e) const { L::construct(e); }
00044 virtual void copy_construct(void *e, const void *src) const { L::copy_construct(e, src); }
00045 virtual void destruct(void *e) const { L::destruct(e); }
00046 virtual size_t class_size() const { return L::class_size(); }
00047
00048 virtual bool equals(const void *lhs, const void *rhs) const {
00049 return L::equals(lhs, rhs);
00050 }
00051
00052 virtual size_t size(const void *container) const { return L::size(container); }
00053 virtual void push(void *container, void *item) const {
00054 L::push_method(container, item);
00055 }
00056 virtual const element_op& get_item_op() const {
00057 return VL::dispatcher_;
00058 }
00059 virtual array_iterator* get_iterator(const void *e) const {
00060 return L::get_iterator(e);
00061 }
00062 };
00063
00064 template<class VL, class L>
00065 struct array_statics {
00066 static array_op_dispatcher<L, VL> dispatcher_;
00067 };
00068
00069 template<class VL, class L>
00070 array_op_dispatcher<L, VL> array_statics<VL, L>::dispatcher_;
00071
00072
00079 template<class T, class L, class VL>
00080 class array : public array_statics<VL, L> {
00081 public:
00082 virtual ~array(){}
00083 typedef L leaf_type;
00084 typedef T value_type;
00085 typedef TYPENAME T::value_type item_type;
00086 typedef VL item_leaf_type;
00087
00088 static void initialize() {
00089 if (!system_type_registry().add(L()))
00090 return;
00091 VL::initialize();
00092 }
00093 static void uninitialize() {}
00094
00095
00096 static void push_method(void *container, const void *item) {
00097 L().methods.push(*static_cast<T*>(container),
00098 *static_cast<const item_type*>(item));
00099 }
00100
00101 static void construct(void *e) {
00102 new (e) T();
00103 }
00104 static void copy_construct(void *e, const void *src) {
00105 new (e) T(*static_cast<const T*>(src));
00106 }
00107 static size_t class_size() { return sizeof(T); }
00108 static void destruct(void *elm) {
00109 static_cast<T*>(elm)->~T();
00110 }
00111
00112 static bool equals(const void *lhs, const void *rhs) {
00113 return array_equals(lhs, rhs, L::dispatcher_, VL::dispatcher_);
00114 }
00115
00116 static size_t size(const void *container) {
00117 return static_cast<const T*>(container)->size();
00118 }
00119
00120 static typed_array_iterator<T> * get_iterator(const void *e) {
00121 return new typed_array_iterator<T>(*static_cast<const T*>(e));
00122 }
00123
00124 static std::string get_xmltype() {
00125 return VL::get_xmltype();
00126 }
00127
00128 static default_op *create_default_op() { return 0; }
00129 };
00130
00131
00132
00138 template<class T, class VL=xiso::leaf<TYPENAME T::value_type> >
00139 class sequential_array : public array<T, sequential_array<T, VL> , VL> {
00140 public:
00141 sequential<T> methods;
00142 };
00143
00144
00150 template<class T, class VL=xiso::leaf<TYPENAME T::value_type> >
00151 class associative_array : public array<T, associative_array<T, VL>, VL> {
00152 public:
00153 associative<T> methods;
00154 };
00155
00156 }
00157
00158 #endif