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