00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #ifndef VERTEX_VECTOR_HPP
00031 #define VERTEX_VECTOR_HPP
00032
00033 #include <vector>
00034
00035 #include <boost/utility.hpp>
00036 #include <boost/tuple/tuple.hpp>
00037
00038 #include <mapnik/vertex.hpp>
00039 #include <mapnik/ctrans.hpp>
00040
00041 namespace mapnik
00042 {
00043 template <typename T>
00044 class vertex_vector : private boost::noncopyable
00045 {
00046 typedef typename T::type value_type;
00047 typedef vertex<value_type,2> vertex_type;
00048 enum block_e {
00049 block_shift = 8,
00050 block_size = 1<<block_shift,
00051 block_mask = block_size - 1,
00052 grow_by = 256
00053 };
00054
00055 private:
00056 unsigned num_blocks_;
00057 unsigned max_blocks_;
00058 value_type** vertexs_;
00059 unsigned char** commands_;
00060 unsigned pos_;
00061 public:
00062
00063 vertex_vector()
00064 : num_blocks_(0),
00065 max_blocks_(0),
00066 vertexs_(0),
00067 commands_(0),
00068 pos_(0) {}
00069
00070 ~vertex_vector()
00071 {
00072 if ( num_blocks_ )
00073 {
00074 value_type** vertexs=vertexs_ + num_blocks_ - 1;
00075 while ( num_blocks_-- )
00076 {
00077 delete [] *vertexs;
00078 --vertexs;
00079 }
00080 delete [] vertexs_;
00081 }
00082 }
00083 unsigned size() const
00084 {
00085 return pos_;
00086 }
00087
00088 void push_back (value_type x,value_type y,unsigned command)
00089 {
00090 unsigned block = pos_ >> block_shift;
00091 if (block >= num_blocks_)
00092 {
00093 allocate_block(block);
00094 }
00095 value_type* vertex = vertexs_[block] + ((pos_ & block_mask) << 1);
00096 unsigned char* cmd= commands_[block] + (pos_ & block_mask);
00097
00098 *cmd = static_cast<unsigned char>(command);
00099 *vertex++ = x;
00100 *vertex = y;
00101 ++pos_;
00102 }
00103 unsigned get_vertex(unsigned pos,value_type* x,value_type* y) const
00104 {
00105 if (pos >= pos_) return SEG_END;
00106 unsigned block = pos >> block_shift;
00107 const value_type* vertex = vertexs_[block] + (( pos & block_mask) << 1);
00108 *x = (*vertex++);
00109 *y = (*vertex);
00110 return commands_[block] [pos & block_mask];
00111 }
00112
00113 void set_capacity(size_t)
00114 {
00115
00116 }
00117
00118 private:
00119 void allocate_block(unsigned block)
00120 {
00121 if (block >= max_blocks_)
00122 {
00123 value_type** new_vertexs = new value_type* [(max_blocks_ + grow_by) * 2];
00124 unsigned char** new_commands = (unsigned char**)(new_vertexs + max_blocks_ + grow_by);
00125 if (vertexs_)
00126 {
00127 std::memcpy(new_vertexs,vertexs_,max_blocks_ * sizeof(value_type*));
00128 std::memcpy(new_commands,commands_,max_blocks_ * sizeof(unsigned char*));
00129 delete [] vertexs_;
00130 }
00131 vertexs_ = new_vertexs;
00132 commands_ = new_commands;
00133 max_blocks_ += grow_by;
00134 }
00135 vertexs_[block] = new value_type [block_size * 2 + block_size / (sizeof(value_type))];
00136 commands_[block] = (unsigned char*)(vertexs_[block] + block_size*2);
00137 ++num_blocks_;
00138 }
00139 };
00140
00141 template <typename T>
00142 struct vertex_vector2 : boost::noncopyable
00143 {
00144 typedef typename T::type value_type;
00145 typedef boost::tuple<value_type,value_type,char> vertex_type;
00146 typedef typename std::vector<vertex_type>::const_iterator const_iterator;
00147 vertex_vector2() {}
00148 unsigned size() const
00149 {
00150 return cont_.size();
00151 }
00152
00153 void push_back (value_type x,value_type y,unsigned command)
00154 {
00155 cont_.push_back(vertex_type(x,y,command));
00156 }
00157 unsigned get_vertex(unsigned pos,value_type* x,value_type* y) const
00158 {
00159 if (pos >= cont_.size()) return SEG_END;
00160 vertex_type const& c = cont_[pos];
00161 *x = boost::get<0>(c);
00162 *y = boost::get<1>(c);
00163 return boost::get<2>(c);
00164 }
00165
00166 const_iterator begin() const
00167 {
00168 return cont_.begin();
00169 }
00170
00171 const_iterator end() const
00172 {
00173 return cont_.end();
00174 }
00175
00176 void set_capacity(size_t size)
00177 {
00178 cont_.reserve(size);
00179 }
00180 private:
00181 std::vector<vertex_type> cont_;
00182 };
00183 }
00184
00185 #endif //VERTEX_VECTOR_HPP