00001 #ifndef INCLUDE_COLLATOR_H
00002 #define INCLUDE_COLLATOR_H
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
00031
00032
00033
00034
00035
00036 #include "Partial.h"
00037 #include "PartialList.h"
00038 #include "PartialUtils.h"
00039
00040 #include <algorithm>
00041
00042
00043 namespace Loris {
00044
00045
00046
00047
00064
00065 class Collator
00066 {
00067
00068
00069 double _fadeTime, _gapTime;
00070
00071
00072 public:
00073
00074
00075
00078 static const double DefaultFadeTime;
00079
00082 static const double DefaultSilentTime;
00083
00084
00085
00105 explicit
00106 Collator( double partialFadeTime = Collator::DefaultFadeTime,
00107 double partialSilentTime = Collator::DefaultSilentTime );
00108
00109
00110
00111
00112
00137 #if ! defined(NO_TEMPLATE_MEMBERS)
00138 template< typename Container >
00139 typename Container::iterator collate( Container & partials );
00140 #else
00141 inline
00142 PartialList::iterator collate( PartialList & partials );
00143 #endif
00144
00146 #if ! defined(NO_TEMPLATE_MEMBERS)
00147 template< typename Container >
00148 typename Container::iterator operator() ( Container & partials );
00149 #else
00150 PartialList::iterator operator() ( PartialList & partials );
00151 #endif
00152
00170 #if ! defined(NO_TEMPLATE_MEMBERS)
00171 template< typename Container >
00172 static typename Container::iterator
00173 collate( Container & partials, double partialFadeTime,
00174 double partialSilentTime );
00175 #else
00176 static inline PartialList::iterator
00177 collate( PartialList & partials, double partialFadeTime,
00178 double partialSilentTime );
00179 #endif
00180
00181
00182 private:
00183
00184
00185
00192 void collateAux( PartialList & unlabled );
00193
00194 };
00195
00196
00197
00198
00221
00222 #if ! defined(NO_TEMPLATE_MEMBERS)
00223 template< typename Container >
00224 typename Container::iterator
00225 Collator::collate( Container & partials )
00226 #else
00227 inline
00228 PartialList::iterator
00229 Collator::collate( PartialList & partials )
00230 #endif
00231 {
00232 #if ! defined(NO_TEMPLATE_MEMBERS)
00233 typedef typename Container::iterator Iterator;
00234 #else
00235 typedef PartialList::iterator Iterator;
00236 #endif
00237
00238
00239
00240
00241
00242 Iterator beginUnlabeled =
00243 std::partition( partials.begin(), partials.end(),
00244 std::not1( PartialUtils::isLabelEqual(0) ) );
00245
00246
00247
00248
00249
00250 PartialList collated( beginUnlabeled, partials.end() );
00251
00252
00253
00254 Partial::label_type labelCollated = 1;
00255 if ( partials.begin() != beginUnlabeled )
00256 {
00257 labelCollated =
00258 1 + std::max_element( partials.begin(), beginUnlabeled,
00259 PartialUtils::compareLabelLess() )->label();
00260 }
00261 if ( labelCollated < 1 )
00262 {
00263 labelCollated = 1;
00264 }
00265
00266
00267 collateAux( collated );
00268
00269
00270 for ( Iterator it = collated.begin(); it != collated.end(); ++it )
00271 {
00272 it->setLabel( labelCollated++ );
00273 }
00274
00275
00276
00277 Iterator endCollated =
00278 std::copy( collated.begin(), collated.end(), beginUnlabeled );
00279
00280
00281 if ( endCollated != partials.end() )
00282 {
00283 typename Iterator::difference_type numLabeled =
00284 std::distance( partials.begin(), beginUnlabeled );
00285
00286 partials.erase( endCollated, partials.end() );
00287
00288
00289 beginUnlabeled = partials.begin();
00290 std::advance( beginUnlabeled, numLabeled );
00291 }
00292 return beginUnlabeled;
00293 }
00294
00295
00296
00297
00301
00302 #if ! defined(NO_TEMPLATE_MEMBERS)
00303 template< typename Container >
00304 typename Container::iterator Collator::operator()( Container & partials )
00305 #else
00306 inline
00307 PartialList::iterator Collator::operator()( PartialList & partials )
00308 #endif
00309 {
00310 return collate( partials );
00311 }
00312
00313
00314
00315
00337
00338 #if ! defined(NO_TEMPLATE_MEMBERS)
00339 template< typename Container >
00340 typename Container::iterator
00341 Collator::collate( Container & partials, double partialFadeTime,
00342 double partialSilentTime )
00343 #else
00344 inline
00345 PartialList::iterator
00346 Collator::collate( PartialList & partials, double partialFadeTime,
00347 double partialSilentTime )
00348 #endif
00349 {
00350 Collator instance( partialFadeTime, partialSilentTime );
00351 return instance.collate( partials );
00352 }
00353
00354 }
00355
00356 #endif