source: trunk/test/Suite.h

Last change on this file was 4359, checked in by Peter, 5 weeks ago

update copyright years using svndigest 0.11 (in contrast to 0.10.x previously)

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