| 252 | // points well, so regardless of why they are there, this function will remove them. |
| 253 | template<typename PointContainer> |
| 254 | void trimEndPoints( PointContainer &points ) |
| 255 | { |
| 256 | if( points.empty() ) |
| 257 | { |
| 258 | return; |
| 259 | } |
| 260 | |
| 261 | // Count how many initial points have an X value matching the first point |
| 262 | typename PointContainer::const_iterator startDuplicates = ++points.begin(); |
| 263 | while( startDuplicates != points.end() && startDuplicates->first == points.begin()->first ) |
| 264 | { |
| 265 | startDuplicates++; |
| 266 | } |
| 267 | // We need to keep one of these points, the rest are duplicates and should be removed |
| 268 | startDuplicates--; |
| 269 | |
| 270 | points.erase( points.begin(), startDuplicates ); |
| 271 | |
| 272 | // Count how many points have an X value matching the last point |
| 273 | typename PointContainer::const_reverse_iterator endDuplicates = ++points.rbegin(); |
| 274 | while( endDuplicates != points.rend() && endDuplicates->first == points.rbegin()->first ) |
| 275 | { |
| 276 | endDuplicates++; |
| 277 | } |
| 278 | |
| 279 | // We need to keep one of these points, the rest are duplicates and should be removed |
| 280 | endDuplicates--; |
| 281 | |
| 282 | points.erase( endDuplicates.base(), points.rbegin().base() ); |
| 283 | |
| 284 | // This originally indicated whether the end point duplication matched the expected multiplicity |
| 285 | // for a certain interpolation. We no longer make assumptions about how the input data handles end |
| 286 | // point multiplicity, and instead just remove any duplicates, so we no longer consider any inputs |
| 287 | // to be invalid. |
| 288 | return; |
| 289 | } |
| 290 | |
| 291 | } |
| 292 |
no test coverage detected