source: trunk/test/Suite.h

Last change on this file was 4089, checked in by Peter, 2 weeks ago

updating copyright years

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 21.9 KB
Line 
1#ifndef _theplu_yat_test_suite_
2#define _theplu_yat_test_suite_
3
4// $Id: Suite.h 4089 2021-09-07 00:56:40Z peter $
5
6/*
7  Copyright (C) 2008 Jari Häkkinen, Peter Johansson
8  Copyright (C) 2009, 2010, 2011, 2013, 2014, 2015, 2016, 2018, 2019, 2020, 2021 Peter Johansson
9
10  This file is part of the yat library, http://dev.thep.lu.se/yat
11
12  The yat library is free software; you can redistribute it and/or
13  modify it under the terms of the GNU General Public License as
14  published by the Free Software Foundation; either version 3 of the
15  License, or (at your option) any later version.
16
17  The yat library is distributed in the hope that it will be useful,
18  but WITHOUT ANY WARRANTY; without even the implied warranty of
19  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20  General Public License for more details.
21
22  You should have received a copy of the GNU General Public License
23  along with yat. If not, see <http://www.gnu.org/licenses/>.
24*/
25
26// ensure that config.h always is included first
27#ifndef YAT_VERSION
28#error header 'config.h' not included
29#endif
30
31#include <yat/utility/config_public.h>
32
33#define YAT_TEST_PROLOGUE "\n=== " << __func__ << " ===\n"
34
35// used to tell automake that test should be skipped
36#define EXIT_SKIP 77
37#define EXIT_HARD_FAILURE 99
38
39// SKIP_BAM_TEST is defined if we should skip bam tests
40#if !defined (YAT_HAVE_HTSLIB) || !defined (HAVE_SAMTOOLS_EXECUTABLE)
41#define SKIP_BAM_TEST
42#endif
43
44#include <yat/utility/VectorMutable.h>
45#include <yat/utility/WeightedIteratorArchetype.h>
46#include <yat/classifier/Target.h>
47
48#include <boost/concept_archetype.hpp>
49#include <boost/concept_check.hpp>
50#include <boost/iterator/iterator_categories.hpp>
51#include <boost/iterator/iterator_concepts.hpp>
52
53#include <iosfwd>
54#include <sstream>
55#include <vector>
56
57namespace theplu {
58namespace yat {
59namespace test {
60
61  /**
62     \internal utility class for tests
63   */
64  class Suite
65  {
66  public:
67    Suite(int argc, char* argv[], bool require_bam=false);
68
69    /**
70     */
71    ~Suite(void);
72
73    /**
74       set ok to 'b && ok'
75
76       \return b
77    */
78    bool add(bool b);
79
80    /**
81       \return In verbose mode std::cerr, else a ofstream to "/dev/null".
82    */
83    std::ostream& err(void) const;
84
85    /**
86       \return true if \f$ |a-b| <= N * \epsilon * min(|a|,|b|) \f$
87       where \f$ \epsilon \f$ is std::numeric_limits<double>().epsilon()
88    */
89    bool equal(double a, double b, unsigned long int N=1);
90
91    /**
92       \return true if |\a a - \a b| <= \a margin
93    */
94    bool equal_fix(double a, double b, double margin=0);
95
96    /**
97       \return true if \f$ |a-b| <= N * sqrt(\epsilon) * min(|a|,|b|) \f$
98       where \f$ \epsilon \f$ is std::numeric_limits<double>().epsilon()
99    */
100    bool equal_sqrt(double a, double b, unsigned long int N=1);
101
102    template<class MATRIX1, class MATRIX2>
103    bool equal_matrix(const MATRIX1& a, const MATRIX2& b,unsigned long int N=1);
104
105    /**
106       apply equal on ranges [first1, last1) and [first2, ...)
107    */
108    template<typename Iterator1, typename Iterator2>
109    bool equal_range(Iterator1 first1, Iterator1 last1, Iterator2 first2,
110                     unsigned int N=1);
111
112    /**
113       apply equal_fix on ranges [first1, last1) and [first2, ...)
114    */
115    template<typename Iterator1, typename Iterator2>
116    bool equal_range_fix(Iterator1 first1, Iterator1 last1, Iterator2 first2,
117                         double margin);
118
119    /**
120      \return true if test is ok
121    */
122    bool ok(void) const;
123
124    /**
125       \return In verbose mode std::cout, else a ofstream to "/dev/null".
126    */
127    std::ostream& out(void) const;
128
129    /**
130       In verbose mode a final message is sent to std::cout.
131
132       If ok() is true: "Test is ok." otherwise
133       "Test failed."
134
135       \return 0 if ok.
136     */
137    int return_value(void) const;
138
139    template<typename TrivialIterator>
140    void test_trivial_iterator(const TrivialIterator&);
141
142    template<typename InputIterator>
143    void test_input_iterator(InputIterator&);
144
145    template<typename OutputIterator>
146    void test_output_iterator(OutputIterator&);
147
148    template<typename ForwardIterator>
149    void test_forward_iterator(ForwardIterator);
150
151    template<typename BidirectionalIterator>
152    void test_bidirectional_iterator(BidirectionalIterator);
153
154    template<typename RandomAccessIterator>
155    void test_random_access_iterator(RandomAccessIterator);
156
157    template<typename Container2D>
158    void test_concept_container2d(const Container2D&);
159
160    template<typename MutableContainer2D>
161    void test_concept_mutable_container2d(MutableContainer2D&);
162
163    /**
164       Function writes to a stream using operator<<, creates a new
165       object using stream constructor, and the new object is written
166       to another stream, and function check if the two outputs are
167       equal.
168    */
169    template<class T>
170    bool test_stream(const T&) const;
171
172    /**
173       This function is similar to add(bool) and could be used to
174       detect/count known issues. When the issue is fixed, one can
175       replace the call to xadd(bool) with a call to add(bool).
176
177       If \a b is false a counter is incremented, which is used to in
178       return_value() to generate some printout on how many known
179       issues were detected.
180
181       If \a b is true, ok_ is set to false, becasue the known issue
182       is no longer an issue and one should replace the call with a
183       call to add(bool).
184     */
185    bool xadd(bool b);
186
187  private:
188    unsigned int known_issues_;
189    bool ok_;
190  };
191
192
193  struct Generator
194  {
195    Generator(void);
196    double operator()(void);
197  private:
198    size_t k_;
199  };
200
201  /**
202     If top source directory is located in /home/strangelove/yat,
203     function returns "/home/strangelove/yat" + "test/" + local_path
204
205     \return absolute path to file
206     \param local_path path relative to srcdir
207   */
208  std::string filename(const std::string& local_path);
209
210  /*
211    class to test (at compile time) that a function (or class) works
212    with a Container2D. Do not run any test using this class because
213    the class is not really functional at run time.
214
215    \see boost/concept_archetype.hpp
216   */
217  template<typename T>
218  class container2d_archetype
219  {
220  public:
221    typedef T value_type;
222    typedef const T& const_reference;
223    typedef const T* const_iterator;
224    typedef const_iterator const_column_iterator;
225    typedef const_iterator const_row_iterator;
226    const_iterator begin(void) const { return &element_; }
227    const_column_iterator begin_column(size_t) const { return &element_; }
228    const_iterator begin_row(size_t) const { return &element_; }
229    const_iterator end(void) const { return NULL; }
230    const_column_iterator end_column(size_t) const { return NULL; }
231    const_iterator end_row(size_t) const { return NULL; }
232    size_t columns(void) const { return 0; }
233    size_t rows(void) const { return 0; }
234    const_reference operator()(size_t row, size_t column) const
235    { return element_; }
236
237  protected:
238    T element_;
239  };
240
241  /*
242    class to test (at compile time) that a function (or class) works
243    with a MutableContainer2D. Do not run any test using this class because
244    the class is not really functional at run time.
245
246    \see boost/concept_archetype.hpp
247   */
248  template<typename T>
249  class mutable_container2d_archetype : public container2d_archetype<T>
250  {
251  public:
252    typedef T& reference;
253    typedef T* iterator;
254    typedef iterator column_iterator;
255    typedef iterator row_iterator;
256    iterator begin(void) { return &this->element_; }
257    column_iterator begin_column(size_t) { return &this->element_; }
258    iterator begin_row(size_t) { return &this->element_; }
259    iterator end(void) { return NULL; }
260    column_iterator end_column(size_t) { return NULL; }
261    iterator end_row(size_t) { return NULL; }
262    reference operator()(size_t row, size_t column)
263    { return this->element_; }
264  };
265
266  /*
267    class to test (at compile time) that a function (or class) works
268    with a Distance. Do not run any test using this class because
269    the class is not really functional at run time.
270
271    \see boost/concept_archetype.hpp
272   */
273  class distance_archetype
274  {
275  public:
276    /// class must be constructible somehow, but we don't wanna assume
277    /// void constructor or any other common constructor so we use the
278    /// signature to allow construction without assuming too much.
279    distance_archetype(const boost::detail::dummy_constructor&) {};
280    distance_archetype(const distance_archetype&) {};
281    template<typename T1, typename T2>
282    double operator()(T1 first1, T1 last1, T2 first2) const { return 0.0; }
283  private:
284    distance_archetype(void);
285    distance_archetype& operator=(const distance_archetype&);
286  };
287
288  /*
289    class to test (at compile time) that a function (or class) works
290    with a NeighborWeighting. Do not run any test using this class because
291    the class is not really functional at run time.
292
293    \see boost/concept_archetype.hpp
294   */
295  class neighbor_weighting_archetype
296  {
297  public:
298    neighbor_weighting_archetype(void) {}
299    void operator()(const utility::VectorBase& distance,
300                    const std::vector<size_t>& k_sorted,
301                    const classifier::Target& target,
302                    utility::VectorMutable& prediction) const {}
303    neighbor_weighting_archetype& operator=(const neighbor_weighting_archetype&)
304    { return *this; }
305  private:
306    neighbor_weighting_archetype(const neighbor_weighting_archetype&) {};
307  };
308
309
310  // compilation tests on iterators
311
312  template<typename Iterator>
313  void test_readable_iterator(Iterator iterator)
314  {
315    BOOST_CONCEPT_ASSERT((boost_concepts::ReadableIterator<Iterator>));
316  }
317
318
319  template<typename Iterator>
320  void test_writable_iterator(Iterator iterator)
321  {
322    BOOST_CONCEPT_ASSERT((boost_concepts::WritableIterator<Iterator>));
323  }
324
325
326  template<typename Iterator>
327  void test_swappable_iterator(Iterator iterator)
328  {
329    BOOST_CONCEPT_ASSERT((boost_concepts::SwappableIterator<Iterator>));
330  }
331
332  template<typename Iterator>
333  void test_lvalue_iterator(Iterator iterator)
334  {
335    BOOST_CONCEPT_ASSERT((boost_concepts::LvalueIterator<Iterator>));
336  }
337
338  template<typename Iterator>
339  void test_incrementable_iterator(Iterator iterator)
340  {
341    BOOST_CONCEPT_ASSERT((boost_concepts::IncrementableIterator<Iterator>));
342  }
343
344  template<typename Iterator>
345  void test_single_pass_iterator(Iterator iterator)
346  {
347    BOOST_CONCEPT_ASSERT((boost_concepts::SinglePassIterator<Iterator>));
348  }
349
350
351  template<typename Iterator>
352  void test_forward_traversal_iterator(Iterator iterator)
353  {
354    BOOST_CONCEPT_ASSERT((boost_concepts::ForwardTraversal<Iterator>));
355  }
356
357
358  template<typename Iterator>
359  void test_bidirectional_traversal_iterator(Iterator iterator)
360  {
361    BOOST_CONCEPT_ASSERT((boost_concepts::BidirectionalTraversal<Iterator>));
362  }
363
364
365  template<typename Iterator>
366  void test_random_access_traversal_iterator(Iterator iterator)
367  {
368    BOOST_CONCEPT_ASSERT((boost_concepts::RandomAccessTraversal<Iterator>));
369  }
370
371
372  // This function pulls out the iterator_category and checks that the
373  // iterator has implemented what is promised in the category.
374  //
375  // Likewise it pulls out the boost::iterator_traversal type and
376  // checks that the traversal is implemented as promised.
377  //
378  // Iterator is a model of input iterator (output iterator makes no
379  // sense as a const iterator)
380  template<typename Iterator>
381  void test_const_iterator(Iterator iterator);
382
383
384  // Similar to test_const_iterator but function also works for
385  // output_iterator and it tests that the iterator is mutable.
386  template<typename Iterator>
387  void test_mutable_iterator(Iterator iterator);
388
389  // functions used by test_const_iterator and test_mutable_iterator
390  namespace detail {
391
392    template<typename Iterator>
393    void test_iterator_traversal(Iterator iterator,
394                                 boost::incrementable_traversal_tag tag)
395    {
396      test_incrementable_iterator(iterator);
397    }
398
399
400    template<typename Iterator>
401    void test_iterator_traversal(Iterator iterator,
402                                 boost::single_pass_traversal_tag tag)
403    {
404      test_single_pass_iterator(iterator);
405    }
406
407
408    template<typename Iterator>
409    void test_iterator_traversal(Iterator iterator,
410                                 boost::forward_traversal_tag tag)
411    {
412      test_forward_traversal_iterator(iterator);
413    }
414
415
416    template<typename Iterator>
417    void test_iterator_traversal(Iterator iterator,
418                                 boost::bidirectional_traversal_tag tag)
419    {
420      test_bidirectional_traversal_iterator(iterator);
421    }
422
423
424    template<typename Iterator>
425    void test_iterator_traversal(Iterator iterator,
426                                 boost::random_access_traversal_tag tag)
427    {
428      test_random_access_traversal_iterator(iterator);
429    }
430
431
432    template<typename Iterator>
433    void test_iterator(Iterator iterator, std::forward_iterator_tag tag)
434    {
435      test_lvalue_iterator(iterator);
436      test_iterator(iterator);
437    }
438
439
440    template<typename Iterator>
441    void test_iterator(Iterator iterator, std::bidirectional_iterator_tag tag)
442    {
443      test_lvalue_iterator(iterator);
444      test_iterator(iterator);
445    }
446
447
448    template<typename Iterator>
449    void test_iterator(Iterator iterator, std::random_access_iterator_tag tag)
450    {
451      test_lvalue_iterator(iterator);
452      test_iterator(iterator);
453    }
454
455
456    // testing forward iterator (or bidirectional or random access)
457    template<typename Iterator>
458    void test_iterator(Iterator iterator)
459    {
460      typename boost::iterator_category<Iterator>::type tag;
461      test_iterator(iterator, tag);
462      typename boost::iterator_traversal<Iterator>::type trav_tag;
463      test_iterator_traversal(iterator, trav_tag);
464    }
465
466
467    template<typename Iterator>
468    void test_mutable_iterator(Iterator iterator, std::output_iterator_tag tag)
469    {
470      test_incrementable_iterator(iterator);
471    }
472
473
474    template<typename Iterator>
475    void test_mutable_iterator(Iterator iterator, std::input_iterator_tag tag)
476    {
477      test_single_pass_iterator(iterator);
478    }
479
480
481    template<typename Iterator>
482    void test_mutable_iterator(Iterator iterator, std::forward_iterator_tag tag)
483    {
484      test_lvalue_iterator(iterator);
485      test_iterator(iterator);
486    }
487
488
489    template<typename Iterator>
490    void test_const_iterator(Iterator iterator, std::input_iterator_tag tag)
491    {
492      test_single_pass_iterator(iterator);
493      test_readable_iterator(iterator);
494    }
495
496
497    template<typename Iterator>
498    void test_const_iterator(Iterator iterator, std::forward_iterator_tag tag)
499    {
500      test_lvalue_iterator(iterator);
501      test_iterator(iterator);
502    }
503
504
505  } // end of namespace detail
506
507
508  // template implementations
509
510  template<class MATRIX1, class MATRIX2>
511  bool Suite::equal_matrix(const MATRIX1& a, const MATRIX2& b,
512                           unsigned long int N)
513  {
514    if (a.rows() != b.rows() || a.columns() != b.columns()) {
515      err() << "incorrect dimensions: "
516            << a.rows() << " x " << a.columns() << " : "
517            << b.rows() << " x " << b.columns() << "\n";
518      return false;
519    }
520    for (size_t i=0; i<a.rows(); ++i)
521      for (size_t j=0; j<a.columns(); ++j)
522        if (!equal(a(i,j), b(i,j), N)) {
523          err() << "  Matrix comparison: row: " << i << " column: " << j
524                << "\n";
525          return false;
526        }
527    return true;
528  }
529
530
531  template<typename Iterator1, typename Iterator2>
532  bool Suite::equal_range(Iterator1 first1, Iterator1 last1, Iterator2 first2,
533                          unsigned int N)
534  {
535    while (first1!=last1){
536      if (!this->equal(*first1, *first2, N) )  {
537        return false;
538      }
539      ++first1;
540      ++first2;
541    }
542    return true;
543  }
544
545
546  template<typename Iterator1, typename Iterator2>
547  bool Suite::equal_range_fix(Iterator1 first1, Iterator1 last1, 
548                              Iterator2 first2, double margin)
549  {
550    while (first1!=last1){
551      if (!this->equal_fix(*first1, *first2, margin) )   {
552        return false;
553      }
554      ++first1;
555      ++first2;
556    }
557    return true;
558  }
559
560
561  // return true if we can write to a write-protected file
562  bool run_as_root(void);
563
564  // function that can be used to avoid warning: '-Wunused-but-set-variable'
565  template<typename T>
566  void avoid_compiler_warning(T) {}
567
568  template<class T>
569  bool Suite::test_stream(const T& t) const
570  {
571    this->err() << "Checking that output stream is valid as an input stream\n";
572    std::stringstream ss;
573    this->err() << "writing to output\n";
574    ss << t;
575    this->err() << "creating a new object from output\n";
576    T t2(ss);
577    std::stringstream ss2;
578    this->err() << "writing to output\n";
579    ss2 << t2;
580    bool ok = ss2.str()==ss.str();
581    if (!ok) {
582      this->err() << "ERROR: first object gave following output:\n"
583                  << ss.str() << "\n"
584                  << "ERROR: and second object gave following output:\n"
585                  << ss2.str() << "\n";
586    }
587    return ok;
588  }
589
590  template<typename TrivialIterator>
591  void Suite::test_trivial_iterator(const TrivialIterator& iter)
592  {
593    err() << "  testing Trivial features" << std::endl;
594    typename std::iterator_traits<TrivialIterator>::value_type tmp = *iter;
595    avoid_compiler_warning(tmp);
596    TrivialIterator default_constructed;
597    avoid_compiler_warning(default_constructed);
598  }
599
600  template<typename InputIterator>
601  void Suite::test_input_iterator(InputIterator& iter)
602  {
603    BOOST_CONCEPT_ASSERT((boost::InputIterator<InputIterator>));
604    test_trivial_iterator(iter);
605    err() << "  testing Input features" << std::endl;
606    // just to check compilation
607    if (false) {
608      ++iter;
609      iter++;
610    }
611  }
612
613  template<typename OutputIterator>
614  void Suite::test_output_iterator(OutputIterator& iter)
615  {
616    err() << "  testing Output features" << std::endl;
617    // OutputIterator should be default constructible and assignable
618    OutputIterator oi;
619    oi = iter;
620    ++oi;
621  }
622
623  template<typename ForwardIterator>
624  void Suite::test_forward_iterator(ForwardIterator iter)
625  {
626    BOOST_CONCEPT_ASSERT((boost::ForwardIterator<ForwardIterator>));
627    test_output_iterator(iter);
628    test_input_iterator(iter);
629    err() << "  testing Forward features" << std::endl;
630
631    typename std::iterator_traits<ForwardIterator>::value_type tmp = *iter;
632    // testing multiple traversing is possible and does not change the data
633    ForwardIterator iter1 = iter;
634    ++iter1;
635    add(iter!=iter1);
636    ForwardIterator iter2 = iter;
637    ++iter2;
638    add(tmp==*iter);
639  }
640
641  template<typename BidirectionalIterator>
642  void Suite::test_bidirectional_iterator(BidirectionalIterator iter)
643  {
644    BOOST_CONCEPT_ASSERT((boost::BidirectionalIterator<BidirectionalIterator>));
645    test_forward_iterator(iter);
646    bool ok_cached = ok();
647    err() << "  testing Bidirectional features" << std::endl;
648    const BidirectionalIterator i = iter;
649    BidirectionalIterator tmp = iter++;
650    if (!add(tmp==i)) {
651      err() << "iter++ does not return iter\n";
652    }
653    if (!add(++tmp==iter)) {
654      err() << "++iter failed\n";
655    }
656    if (!add(--tmp==i)) {
657      err() << "--iter failed\n";
658    }
659    tmp = iter--;
660    if (!add(--tmp==iter))
661      err() << "iter-- failed" << std::endl;
662    if (ok_cached && !ok())
663      err() << "failed" << std::endl;
664  }
665
666  template<typename RandomAccessIterator>
667  void Suite::test_random_access_iterator(RandomAccessIterator iter)
668  {
669    BOOST_CONCEPT_ASSERT((boost::RandomAccessIterator<RandomAccessIterator>));
670    test_bidirectional_iterator(iter);
671    err() << "  testing RandomAccess features" << std::endl;
672    bool ok_cached = ok();
673    RandomAccessIterator iter2 = iter;
674    iter2 += 1;
675    iter2 -= 1;
676    RandomAccessIterator& iter3 = (iter2 += 1);
677    RandomAccessIterator& iter4 = (iter3 -= 1);
678    if (!add(iter2 == iter4))
679      err() << "operator-(int) failed" << std::endl;
680    add(++iter2 == iter3);
681
682    RandomAccessIterator iter5 = iter + 0;
683    RandomAccessIterator iter6 = 0 + iter;
684    add(iter6 == iter5);
685
686    RandomAccessIterator iter7 = iter - 0;
687    add(iter7 == iter);
688    add(iter7 - iter == 0);
689    add(! (iter7<iter));
690
691    typename RandomAccessIterator::value_type tmp = iter[0];
692    typename RandomAccessIterator::value_type tmp2 = *iter;
693    tmp = tmp; // avoid compiler warning
694    if (!add(tmp == tmp2))
695      err() << "operator[] failed" << std::endl;
696    if (!add(iter[0] == *iter))
697      err() << "operator[] failed" << std::endl;
698    if (ok_cached && !ok())
699      err() << "failed" << std::endl;
700  }
701
702  template<typename Container2D>
703  void Suite::test_concept_container2d(const Container2D& c)
704  {
705    typedef typename Container2D::value_type value_type;
706    typedef typename Container2D::const_reference const_reference;
707    typedef typename Container2D::const_iterator const_iterator;
708    typedef typename Container2D::const_column_iterator const_column_iterator;
709    typedef typename Container2D::const_row_iterator const_row_iterator;
710    const_iterator ci = c.begin();
711    const_column_iterator cci = c.begin_column(0);
712    const_row_iterator cri = c.begin_row(0);
713    ci = c.end();
714    cci = c.end_column(0);
715    cri = c.end_row(0);
716    size_t cols = c.columns();
717    size_t rows = c.rows();
718    // just to avoid compiler warning
719    avoid_compiler_warning(cols);
720    avoid_compiler_warning(rows);
721    const_reference x = c(0,0);
722    value_type y;
723    y = x;
724    avoid_compiler_warning(y);
725  }
726
727  template<typename MutableContainer2D>
728  void Suite::test_concept_mutable_container2d(MutableContainer2D& mc)
729  {
730    test_concept_container2d(mc);
731    typedef typename MutableContainer2D::reference reference;
732    typedef typename MutableContainer2D::iterator iterator;
733    typedef typename MutableContainer2D::column_iterator column_iterator;
734    typedef typename MutableContainer2D::row_iterator row_iterator;
735    iterator i = mc.begin();
736    column_iterator ci = mc.begin_column(0);
737    row_iterator ri = mc.begin_row(0);
738    *i = *ci;
739    *ci = *i;
740    *ri = *i;
741    i = mc.end();
742    ci = mc.end_column(0);
743    ri = mc.end_row(0);
744    reference x = mc(0,0);
745    x = *mc.begin();
746  }
747
748
749  template<typename Iterator>
750  void test_const_iterator(Iterator iterator)
751  {
752    typename boost::iterator_category<Iterator>::type tag;
753    detail::test_const_iterator(iterator, tag);
754  }
755
756
757  template<typename Iterator>
758  void test_mutable_iterator(Iterator iterator)
759  {
760    typename boost::iterator_category<Iterator>::type tag;
761    detail::test_mutable_iterator(iterator, tag);
762    test_writable_iterator(iterator);
763  }
764
765
766  // For convenience to create data iterator. This class typedefs four
767  // classes that can be conveniently constructed in tests
768  // (const/mutable and weighted/unweighted. Traversal
769  // is expected to be one of:
770  //// boost::incrementable_traversal_tag (problematic with unweighted)
771  // boost::single_pass_traversal_tag (problematic with unweighted)
772  // boost::forward_traversal_tag
773  // boost::bidirectional_traversal_tag
774  // boost::random_access_traversal_tag
775  template<typename Traversal>
776  struct DataIterator
777  {
778    typedef boost::iterator_archetype<
779      double,
780      boost::iterator_archetypes::readable_iterator_t,
781      Traversal
782      > unweighted_const_iterator;
783
784    typedef boost::iterator_archetype<
785      double,
786      boost::iterator_archetypes::readable_writable_iterator_t,
787      Traversal
788      > unweighted_iterator;
789
790
791    typedef utility::WeightedIteratorArchetype<
792      boost::iterator_archetypes::readable_iterator_t, Traversal
793      >
794    weighted_const_iterator;
795
796    typedef utility::WeightedIteratorArchetype<
797      boost::iterator_archetypes::readable_writable_iterator_t,
798      Traversal
799      >
800    weighted_iterator;
801  };
802}}}
803
804#endif
Note: See TracBrowser for help on using the repository browser.