Mercurial > foo_out_sdl
diff foosdk/sdk/pfc/list.h @ 1:20d02a178406 default tip
*: check in everything else
yay
| author | Paper <paper@tflc.us> |
|---|---|
| date | Mon, 05 Jan 2026 02:15:46 -0500 |
| parents | |
| children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/foosdk/sdk/pfc/list.h Mon Jan 05 02:15:46 2026 -0500 @@ -0,0 +1,722 @@ +#pragma once +#include "bsearch.h" +#include "sort.h" +#include "primitives.h" +#include "traits.h" +#include "bit_array.h" +#include "bit_array_impl.h" +#include "order_helper.h" +#include "array.h" + +#include <iterator> + +namespace pfc { + template<typename arr_t> + class list_const_iterator { + typedef list_const_iterator<arr_t> self_t; + public: + typedef ptrdiff_t difference_type; + typedef typename arr_t::t_item value_type; + typedef const value_type* pointer; + typedef const value_type& reference; + typedef std::random_access_iterator_tag iterator_category; + + list_const_iterator(arr_t* arr, size_t index) : m_arr(arr), m_index(index) {} + void operator++() { ++m_index; } + void operator--() { --m_index; } + value_type operator*() const { return m_arr->get_item(m_index); } + + bool operator==(const self_t& other) const { PFC_ASSERT(m_arr == other.m_arr); return m_index == other.m_index; } + bool operator!=(const self_t& other) const { PFC_ASSERT(m_arr == other.m_arr); return m_index != other.m_index; } + bool operator>(const self_t& other) const { PFC_ASSERT(m_arr == other.m_arr); return m_index > other.m_index; } + bool operator<(const self_t& other) const { PFC_ASSERT(m_arr == other.m_arr); return m_index < other.m_index; } + bool operator>=(const self_t& other) const { PFC_ASSERT(m_arr == other.m_arr); return m_index >= other.m_index; } + bool operator<=(const self_t& other) const { PFC_ASSERT(m_arr == other.m_arr); return m_index <= other.m_index; } + + void operator+=(size_t v) { m_index += v; } + self_t operator+(size_t v) { self_t ret = *this; ret += v; return ret; } + difference_type operator-(self_t const& other) const { PFC_ASSERT(m_arr == other.m_arr); return m_index - other.m_index; } + void operator-=(size_t v) { m_index -= v; } + private: + arr_t* m_arr; + size_t m_index; + }; +} + +namespace std { + template<typename arr_t> struct iterator_traits< pfc::list_const_iterator<arr_t> > { + typedef ptrdiff_t difference_type; + typedef typename arr_t::t_item value_type; + typedef value_type* pointer; + typedef value_type& reference; + typedef std::random_access_iterator_tag iterator_category; + }; +} + +namespace pfc { + +template<typename T> +class NOVTABLE list_base_const_t { +private: typedef list_base_const_t<T> t_self; +public: + typedef T t_item; + virtual t_size get_count() const = 0; + virtual void get_item_ex(T& p_out, t_size n) const = 0; + + inline t_size get_size() const {return get_count();} + inline size_t size() const { return get_count(); } + + inline T get_item(t_size n) const {T temp; get_item_ex(temp,n); return temp;} + inline T operator[](t_size n) const {T temp; get_item_ex(temp,n); return temp;} + + template<typename t_compare> + t_size find_duplicates_sorted_t(t_compare p_compare,bit_array_var & p_out) const + { + return ::pfc::find_duplicates_sorted_t<list_base_const_t<T> const &,t_compare>(*this,get_count(),p_compare,p_out); + } + + template<typename t_compare,typename t_permutation> + t_size find_duplicates_sorted_permutation_t(t_compare p_compare,t_permutation const & p_permutation,bit_array_var & p_out) + { + return ::pfc::find_duplicates_sorted_permutation_t<list_base_const_t<T> const &,t_compare,t_permutation>(*this,get_count(),p_compare,p_permutation,p_out); + } + + template<typename t_search> + t_size find_item(const t_search & p_item) const//returns index of first occurance, infinite if not found + { + t_size n,max = get_count(); + for(n=0;n<max;n++) + if (get_item(n)==p_item) return n; + return SIZE_MAX; + } + + template<typename t_search> + inline bool have_item(const t_search & p_item) const {return find_item<t_search>(p_item)!=SIZE_MAX;} + + + template<typename t_compare, typename t_param> + bool bsearch_t(t_compare p_compare,t_param const & p_param,t_size &p_index) const { + return ::pfc::bsearch_t(get_count(),*this,p_compare,p_param,p_index); + } + + template<typename t_compare,typename t_param,typename t_permutation> + bool bsearch_permutation_t(t_compare p_compare,t_param const & p_param,const t_permutation & p_permutation,t_size & p_index) const { + return ::pfc::bsearch_permutation_t(get_count(),*this,p_compare,p_param,p_permutation,p_index); + } + + template<typename t_compare,typename t_permutation> + void sort_get_permutation_t(t_compare p_compare,t_permutation const & p_permutation) const { + ::pfc::sort_get_permutation_t<list_base_const_t<T>,t_compare,t_permutation>(*this,p_compare,get_count(),p_permutation); + } + + template<typename t_compare,typename t_permutation> + void sort_stable_get_permutation_t(t_compare p_compare,t_permutation const & p_permutation) const { + ::pfc::sort_stable_get_permutation_t<list_base_const_t<T>,t_compare,t_permutation>(*this,p_compare,get_count(),p_permutation); + } + + template<typename t_callback> + void enumerate(t_callback & p_callback) const { + for(t_size n = 0, m = get_count(); n < m; ++n ) { + p_callback( (*this)[n] ); + } + } + + static bool g_equals(const t_self & item1, const t_self & item2) { + const t_size count = item1.get_count(); + if (count != item2.get_count()) return false; + for(t_size walk = 0; walk < count; ++walk) if (item1[walk] != item2[walk]) return false; + return true; + } + bool operator==(const t_self & item2) const {return g_equals(*this,item2);} + bool operator!=(const t_self & item2) const {return !g_equals(*this,item2);} + + typedef list_const_iterator< const t_self > iterator; + typedef iterator const_iterator; + + iterator begin() const { return iterator(this, 0); } + iterator end() const { return iterator(this, get_count()); } +protected: + list_base_const_t() {} + ~list_base_const_t() {} + + list_base_const_t(const t_self &) {} + void operator=(const t_self &) {} + +}; + + +template<typename T> +class list_single_ref_t : public list_base_const_t<T> +{ +public: + list_single_ref_t(const T & p_item,t_size p_count = 1) : m_item(p_item), m_count(p_count) {} + t_size get_count() const {return m_count;} + void get_item_ex(T& p_out, t_size n) const { PFC_ASSERT(n < m_count); (void)n; p_out = m_item; } +private: + const T & m_item; + t_size m_count; +}; + +template<typename item_t> +inline list_single_ref_t<item_t> list_single(item_t const& i, size_t n = 1) { return list_single_ref_t<item_t>(i, n); } + +template<typename T> +class list_partial_ref_t : public list_base_const_t<T> +{ +public: + list_partial_ref_t(const list_base_const_t<T> & p_list,t_size p_base,t_size p_count) + : m_list(p_list), m_base(p_base), m_count(p_count) + { + PFC_ASSERT(m_base + m_count <= m_list.get_count()); + } + +private: + const list_base_const_t<T> & m_list; + t_size m_base,m_count; + + t_size get_count() const {return m_count;} + void get_item_ex(T & p_out,t_size n) const {m_list.get_item_ex(p_out,n+m_base);} +}; + +template<typename T,typename A> +class list_const_array_t : public list_base_const_t<T> +{ +public: + inline list_const_array_t(A p_data,t_size p_count) : m_data(p_data), m_count(p_count) {} + t_size get_count() const {return m_count;} + void get_item_ex(T & p_out,t_size n) const {p_out = m_data[n];} +private: + A m_data; + t_size m_count; +}; +template<typename t_array> +class list_const_array_ref_t : public list_base_const_t<typename t_array::t_item> { +public: + list_const_array_ref_t(const t_array & data) : m_data(data) {} + t_size get_count() const {return m_data.get_size();} + void get_item_ex(typename t_array::t_item & out, t_size n) const {out = m_data[n];} +private: + const t_array & m_data; +}; + +template<typename to,typename from> +class list_const_cast_t : public list_base_const_t<to> +{ +public: + list_const_cast_t(const list_base_const_t<from> & p_from) : m_from(p_from) {} + t_size get_count() const {return m_from.get_count();} + void get_item_ex(to & p_out,t_size n) const + { + from temp; + m_from.get_item_ex(temp,n); + p_out = temp; + } +private: + const list_base_const_t<from> & m_from; +}; + +template<typename T,typename A> +class ptr_list_const_array_t : public list_base_const_t<T*> +{ +public: + inline ptr_list_const_array_t(A p_data,t_size p_count) : m_data(p_data), m_count(p_count) {} + t_size get_count() const {return m_count;} + void get_item_ex(T* & p_out,t_size n) const {p_out = &m_data[n];} +private: + A m_data; + t_size m_count; +}; +template<typename T> +class list_const_ptr_t : public list_base_const_t<T> +{ +public: + inline list_const_ptr_t(const T * p_data,t_size p_count) : m_data(p_data), m_count(p_count) {} + t_size get_count() const {return m_count;} + void get_item_ex(T & p_out,t_size n) const {p_out = m_data[n];} +private: + const T * m_data; + t_size m_count; +}; + +template<typename T> +class NOVTABLE list_base_t : public list_base_const_t<T> { +private: + typedef list_base_t<T> t_self; + typedef const list_base_const_t<T> t_self_const; +public: + class NOVTABLE sort_callback + { + public: + virtual int compare(const T& p_item1,const T& p_item2) = 0; + }; + + virtual void filter_mask(const bit_array & mask) = 0; + virtual t_size insert_items(const list_base_const_t<T> & items,t_size base) = 0; + virtual void reorder_partial(t_size p_base,const t_size * p_data,t_size p_count) = 0; + virtual void sort(sort_callback & p_callback) = 0; + virtual void sort_stable(sort_callback & p_callback) = 0; + virtual void replace_item(t_size p_index,const T& p_item) = 0; + virtual void swap_item_with(t_size p_index,T & p_item) = 0; + virtual void swap_items(t_size p_index1,t_size p_index2) = 0; + + inline void reorder(const t_size * p_data) {reorder_partial(0,p_data,this->get_count());} + + inline t_size insert_item(const T & item,t_size base) {return insert_items(list_single_ref_t<T>(item),base);} + t_size insert_items_repeat(const T & item,t_size num,t_size base) {return insert_items(list_single_ref_t<T>(item,num),base);} + inline t_size add_items_repeat(T item,t_size num) {return insert_items_repeat(item,num,SIZE_MAX);} + t_size insert_items_fromptr(const T* source,t_size num,t_size base) {return insert_items(list_const_ptr_t<T>(source,num),base);} + inline t_size add_items_fromptr(const T* source,t_size num) {return insert_items_fromptr(source,num,SIZE_MAX);} + + inline t_size add_items(const list_base_const_t<T> & items) {return insert_items(items,SIZE_MAX);} + inline t_size add_item(const T& item) {return insert_item(item,SIZE_MAX);} + + inline void remove_mask(const bit_array & mask) {filter_mask(bit_array_not(mask));} + inline void remove_all() {filter_mask(bit_array_false());} + inline void truncate(t_size val) {if (val < this->get_count()) remove_mask(bit_array_range(val,this->get_count()-val,true));} + + inline T replace_item_ex(t_size p_index,const T & p_item) {T ret = p_item;swap_item_with(p_index,ret);return ret;} + + inline T operator[](t_size n) const {return this->get_item(n);} + + template<typename t_compare> + class sort_callback_impl_t : public sort_callback + { + public: + sort_callback_impl_t(t_compare p_compare) : m_compare(p_compare) {} + int compare(const T& p_item1,const T& p_item2) {return m_compare(p_item1,p_item2);} + private: + t_compare m_compare; + }; + + class sort_callback_auto : public sort_callback + { + public: + int compare(const T& p_item1,const T& p_item2) {return ::pfc::compare_t(p_item1,p_item2);} + }; + + void sort() {sort_callback_auto cb;sort(cb);} + template<typename t_compare> void sort_t(t_compare p_compare) {sort_callback_impl_t<t_compare> cb(p_compare);sort(cb);} + template<typename t_compare> void sort_stable_t(t_compare p_compare) {sort_callback_impl_t<t_compare> cb(p_compare); sort_stable(cb);} + + template<typename t_compare> void sort_remove_duplicates_t(t_compare p_compare) + { + sort_t<t_compare>(p_compare); + bit_array_bittable array(this->get_count()); + if (this->template find_duplicates_sorted_t<t_compare>(p_compare,array) > 0) + remove_mask(array); + } + + template<typename t_compare> void sort_stable_remove_duplicates_t(t_compare p_compare) + { + sort_stable_t<t_compare>(p_compare); + bit_array_bittable array(this->get_count()); + if (this->template find_duplicates_sorted_t<t_compare>(p_compare,array) > 0) + remove_mask(array); + } + + + template<typename t_compare> void remove_duplicates_t(t_compare p_compare) + { + order_helper order(this->get_count()); + sort_get_permutation_t<t_compare,order_helper&>(p_compare,order); + bit_array_bittable array(this->get_count()); + if (this->template find_duplicates_sorted_permutation_t<t_compare,order_helper const&>(p_compare,order,array) > 0) + remove_mask(array); + } + + template<typename t_func> + void for_each(t_func p_func) { + t_size n,max=this->get_count(); + for(n=0;n<max;n++) p_func(this->get_item(n)); + } + + template<typename t_func> + void for_each(t_func p_func,const bit_array & p_mask) { + t_size n,max=this->get_count(); + for(n=p_mask.find(true,0,max);n<max;n=p_mask.find(true,n+1,max-n-1)) { + p_func(this->get_item(n)); + } + } + + template<typename t_releasefunc> + void remove_mask_ex(const bit_array & p_mask,t_releasefunc p_func) { + this->template for_each<t_releasefunc>(p_func,p_mask); + remove_mask(p_mask); + } + + template<typename t_releasefunc> + void remove_all_ex(t_releasefunc p_func) { + this->template for_each<t_releasefunc>(p_func); + remove_all(); + } + + template<typename t_in> t_self & operator=(t_in const & source) {remove_all(); add_items(source); return *this;} + template<typename t_in> t_self & operator+=(t_in const & p_source) {add_item(p_source); return *this;} + template<typename t_in> t_self & operator|=(t_in const & p_source) {add_items(p_source); return *this;} + +protected: + list_base_t() {} + ~list_base_t() {} + list_base_t(const t_self&) {} + void operator=(const t_self&) {} +}; + + +template<typename T,typename t_storage> +class list_impl_t : public list_base_t<T> +{ +public: + typedef list_base_t<T> t_base; + typedef list_impl_t<T, t_storage> t_self; + list_impl_t() {} + list_impl_t(const t_self & p_source) { add_items(p_source); } + + void copy(const t_self& p_source) { m_buffer = p_source.m_buffer; } + void move(t_self& p_source) { m_buffer = std::move(p_source.m_buffer); } + + void prealloc(t_size count) {m_buffer.prealloc(count);} + + void set_count(t_size p_count) {m_buffer.set_size(p_count);} + void set_size(t_size p_count) {m_buffer.set_size(p_count);} + + template<typename t_in> + t_size _insert_item_t(const t_in & item, t_size idx) { + return ::pfc::insert_t(m_buffer, item, idx); + } + template<typename t_in> + t_size insert_item(const t_in & item, t_size idx) { + return _insert_item_t(item, idx); + } + + t_size insert_item(const T& item,t_size idx) { + return _insert_item_t(item, idx); + } + + T remove_by_idx(t_size idx) + { + T ret = std::move(m_buffer[idx]); + t_size n; + t_size max = m_buffer.get_size(); + for(n=idx+1;n<max;n++) { + m_buffer[n - 1] = std::move(m_buffer[n]); + } + m_buffer.set_size(max-1); + return ret; + } + + + inline void get_item_ex(T& p_out,t_size n) const + { + PFC_ASSERT(n>=0); + PFC_ASSERT(n<get_size()); + p_out = m_buffer[n]; + } + + inline const T& get_item_ref(t_size n) const + { + PFC_ASSERT(n>=0); + PFC_ASSERT(n<get_size()); + return m_buffer[n]; + } + + inline T get_item(t_size n) const + { + PFC_ASSERT(n >= 0); + PFC_ASSERT(n < get_size() ); + return m_buffer[n]; + }; + + inline t_size get_count() const {return m_buffer.get_size();} + inline t_size get_size() const {return m_buffer.get_size();} + inline size_t size() const { return m_buffer.get_size(); } + + inline const T & operator[](t_size n) const + { + PFC_ASSERT(n>=0); + PFC_ASSERT(n<get_size()); + return m_buffer[n]; + } + + inline const T* get_ptr() const {return m_buffer.get_ptr();} + inline T* get_ptr() {return m_buffer.get_ptr();} + + inline T& operator[](t_size n) {return m_buffer[n];} + + inline void remove_from_idx(t_size idx,t_size num) + { + remove_mask(bit_array_range(idx,num)); + } + + t_size _insert_items_v(const list_base_const_t<T> & source,t_size base) { //workaround for inefficient operator[] on virtual-interface-accessed lists + t_size count = get_size(); + if (base>count) base = count; + t_size num = source.get_count(); + m_buffer.set_size(count+num); + if (count > base) { + for(t_size n=count-1;(int)n>=(int)base;n--) { + ::pfc::move_t(m_buffer[n+num],m_buffer[n]); + } + } + + for(t_size n=0;n<num;n++) { + source.get_item_ex(m_buffer[n+base],n); + } + return base; + } + // use _insert_items_v where it's more efficient + t_size insert_items(const list_base_const_t<T> & source,t_size base) {return _insert_items_v(source, base);} + t_size insert_items(const list_base_t<T> & source,t_size base) {return _insert_items_v(source, base);} + + template<typename t_in> + t_size insert_items(const t_in & source,t_size base) { + t_size count = get_size(); + if (base>count) base = count; + t_size num = array_size_t(source); + m_buffer.set_size(count+num); + if (count > base) { + for(t_size n=count-1;(int)n>=(int)base;n--) { + ::pfc::move_t(m_buffer[n+num],m_buffer[n]); + } + } + + for(t_size n=0;n<num;n++) { + m_buffer[n+base] = source[n]; + } + return base; + } + + template<typename t_in> + void add_items(const t_in & in) {insert_items(in, SIZE_MAX);} + + void get_items_mask(list_impl_t<T,t_storage> & out,const bit_array & mask) + { + mask.walk( get_size(), [&] (size_t n) { + out.add_item(m_buffer[n]); + } ); + } + + void filter_mask(const bit_array & mask) + { + t_size n,count = get_size(), total = 0; + + n = total = mask.find(false,0,count); + + if (n<count) { + for(n=mask.find(true,n+1,count-n-1);n<count;n=mask.find(true,n+1,count-n-1)) + ::pfc::move_t(m_buffer[total++],m_buffer[n]); + + m_buffer.set_size(total); + } + } + + void replace_item(t_size idx,const T& item) + { + PFC_ASSERT(idx>=0); + PFC_ASSERT(idx<get_size()); + m_buffer[idx] = item; + } + + void sort() + { + ::pfc::sort_callback_impl_auto_wrap_t<t_storage> wrapper(m_buffer); + ::pfc::sort(wrapper,get_size()); + } + + template<typename t_compare> + void sort_t(t_compare p_compare) + { + ::pfc::sort_callback_impl_simple_wrap_t<t_storage,t_compare> wrapper(m_buffer,p_compare); + ::pfc::sort(wrapper,get_size()); + } + + template<typename t_compare> + void sort_stable_t(t_compare p_compare) + { + ::pfc::sort_callback_impl_simple_wrap_t<t_storage,t_compare> wrapper(m_buffer,p_compare); + ::pfc::sort_stable(wrapper,get_size()); + } + inline void reorder_partial(t_size p_base,const t_size * p_order,t_size p_count) + { + PFC_ASSERT(p_base+p_count<=get_size()); + ::pfc::reorder_partial_t(m_buffer,p_base,p_order,p_count); + } + + template<typename t_compare> + t_size find_duplicates_sorted_t(t_compare p_compare,bit_array_var & p_out) const + { + return ::pfc::find_duplicates_sorted_t<list_impl_t<T,t_storage> const &,t_compare>(*this,get_size(),p_compare,p_out); + } + + template<typename t_compare,typename t_permutation> + t_size find_duplicates_sorted_permutation_t(t_compare p_compare,t_permutation p_permutation,bit_array_var & p_out) + { + return ::pfc::find_duplicates_sorted_permutation_t<list_impl_t<T,t_storage> const &,t_compare,t_permutation>(*this,get_size(),p_compare,p_permutation,p_out); + } + + + void move_from(t_self & other) { + remove_all(); + m_buffer = std::move(other.m_buffer); + } + + T* begin() { return m_buffer.get_ptr(); } + T* end() { return m_buffer.get_ptr() + get_size(); } + const T* begin() const { return m_buffer.get_ptr(); } + const T* end() const { return m_buffer.get_ptr() + get_size(); } + +private: + class sort_callback_wrapper + { + public: + explicit inline sort_callback_wrapper(typename t_base::sort_callback & p_callback) : m_callback(p_callback) {} + inline int operator()(const T& item1,const T& item2) const {return m_callback.compare(item1,item2);} + private: + typename t_base::sort_callback & m_callback; + }; +public: + void sort(typename t_base::sort_callback & p_callback) + { + sort_t(sort_callback_wrapper(p_callback)); + } + + void sort_stable(typename t_base::sort_callback & p_callback) + { + sort_stable_t(sort_callback_wrapper(p_callback)); + } + + void remove_mask(const bit_array & mask) {filter_mask(bit_array_not(mask));} + + void remove_mask(const bool * mask) {remove_mask(bit_array_table(mask,get_size()));} + void filter_mask(const bool * mask) {filter_mask(bit_array_table(mask,get_size()));} + + size_t add_item(const T& item) { + return pfc::append_t(m_buffer, item); + } + + size_t add_item(T&& item) { + return pfc::append_t(m_buffer, std::move(item)); + } + + template<typename t_in> t_size add_item(const t_in & item) { + return pfc::append_t(m_buffer, item); + } + + void remove_all() {remove_mask(bit_array_true());} + + void remove_item(const T& item) + { + t_size n,max = get_size(); + bit_array_bittable mask(max); + for(n=0;n<max;n++) + mask.set(n,get_item(n)==item); + remove_mask(mask); + } + + void swap_item_with(t_size p_index,T & p_item) + { + PFC_ASSERT(p_index < get_size()); + swap_t(m_buffer[p_index],p_item); + } + + void swap_items(t_size p_index1,t_size p_index2) + { + PFC_ASSERT(p_index1 < get_size()); + PFC_ASSERT(p_index2 < get_size()); + swap_t(m_buffer[p_index1],m_buffer[p_index2]); + } + + inline static void g_swap(list_impl_t<T,t_storage> & p_item1,list_impl_t<T,t_storage> & p_item2) + { + swap_t(p_item1.m_buffer,p_item2.m_buffer); + } + + template<typename t_search> + t_size find_item(const t_search & p_item) const//returns index of first occurance, infinite if not found + { + t_size n,max = get_size(); + for(n=0;n<max;n++) + if (m_buffer[n]==p_item) return n; + return SIZE_MAX; + } + + template<typename t_search> + inline bool have_item(const t_search & p_item) const {return this->template find_item<t_search>(p_item)!=SIZE_MAX;} + + template<typename t_in> t_self & operator=(t_in const & source) {remove_all(); add_items(source); return *this;} + template<typename t_in> t_self & operator+=(t_in const & p_source) {add_item(p_source); return *this;} + template<typename t_in> t_self & operator|=(t_in const & p_source) {add_items(p_source); return *this;} +protected: + t_storage m_buffer; +}; + +template<typename t_item, template<typename> class t_alloc = alloc_fast > +class list_t : public list_impl_t<t_item,array_t<t_item,t_alloc> > { +public: + typedef list_t<t_item, t_alloc> t_self; + template<typename t_in> const t_self & operator=(t_in const & source) {this->remove_all(); this->add_items(source); return *this;} + template<typename t_in> const t_self & operator+=(t_in const & p_source) {this->add_item(p_source); return *this;} + template<typename t_in> const t_self & operator|=(t_in const & p_source) {this->add_items(p_source); return *this;} + + const t_self& operator=(t_self const& other) { this->copy(other); return *this; } + const t_self& operator=(t_self&& other) { this->move(other); return *this; } + + list_t() {} + list_t(t_self const& other) { this->copy(other); } + list_t(t_self&& other) { this->move(other); } +}; + +template<typename t_item, t_size p_fixed_count, template<typename> class t_alloc = alloc_fast > +class list_hybrid_t : public list_impl_t<t_item,array_hybrid_t<t_item,p_fixed_count,t_alloc> > { +public: + typedef list_hybrid_t<t_item, p_fixed_count, t_alloc> t_self; + template<typename t_in> t_self & operator=(t_in const & source) {this->remove_all(); this->add_items(source); return *this;} + template<typename t_in> t_self & operator+=(t_in const & p_source) {this->add_item(p_source); return *this;} + template<typename t_in> t_self & operator|=(t_in const & p_source) {this->add_items(p_source); return *this;} +}; + +template<typename T> +class ptr_list_const_cast_t : public list_base_const_t<const T *> +{ +public: + inline ptr_list_const_cast_t(const list_base_const_t<T*> & p_param) : m_param(p_param) {} + t_size get_count() const {return m_param.get_count();} + void get_item_ex(const T * & p_out,t_size n) const {T* temp; m_param.get_item_ex(temp,n); p_out = temp;} +private: + const list_base_const_t<T*> & m_param; + +}; + + +template<typename T,typename P> +class list_const_permutation_t : public list_base_const_t<T> +{ +public: + inline list_const_permutation_t(const list_base_const_t<T> & p_list,P p_permutation) : m_list(p_list), m_permutation(p_permutation) {} + t_size get_count() const {return m_list.get_count();} + void get_item_ex(T & p_out,t_size n) const {m_list.get_item_ex(p_out,m_permutation[n]);} +private: + P m_permutation; + const list_base_const_t<T> & m_list; +}; + + +template<class T> +class list_permutation_t : public list_base_const_t<T> +{ +public: + t_size get_count() const {return m_count;} + void get_item_ex(T & p_out,t_size n) const {m_base.get_item_ex(p_out,m_order[n]);} + list_permutation_t(const list_base_const_t<T> & p_base,const t_size * p_order,t_size p_count) + : m_base(p_base), m_order(p_order), m_count(p_count) + { + PFC_ASSERT(m_base.get_count() >= m_count); + } +private: + const list_base_const_t<T> & m_base; + const t_size * m_order; + t_size m_count; +}; + +template<typename item, template<typename> class alloc> class traits_t<list_t<item, alloc> > : public combine_traits<traits_t<alloc<item> >, traits_vtable> {}; + +}
