1/*
2 * Copyright (C) 2009 The Android Open Source Project
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *  * Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 *  * Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in
12 *    the documentation and/or other materials provided with the
13 *    distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
18 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
22 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29#include "../include/iterator"
30#ifndef ANDROID_ASTL_ITERATOR__
31#error "Wrong header included!!"
32#endif
33#include "common.h"
34
35namespace android {
36
37// Iterators used in tests.
38struct Input {
39    typedef std::input_iterator_tag iterator_category;
40    typedef int                     value_type;
41    typedef ptrdiff_t               difference_type;
42    typedef int*                    pointer;
43    typedef int&                    reference;
44};
45
46struct Forward {
47    typedef std::forward_iterator_tag iterator_category;
48    typedef int                       value_type;
49    typedef ptrdiff_t                 difference_type;
50    typedef int*                      pointer;
51    typedef int&                      reference;
52};
53
54struct Bidirectional {
55    typedef std::bidirectional_iterator_tag iterator_category;
56    typedef int                             value_type;
57    typedef ptrdiff_t                       difference_type;
58    typedef int*                            pointer;
59    typedef int&                            reference;
60};
61
62struct Random {
63    typedef std::random_access_iterator_tag iterator_category;
64    typedef int                             value_type;
65    typedef ptrdiff_t                       difference_type;
66    typedef int*                            pointer;
67    typedef int&                            reference;
68};
69
70// Enum and helper functions to map an iterator tag to an int.
71enum Category {UNKNOWN, INPUT, FORWARD, BIDIRECTIONAL, RANDOM};
72
73template<typename _Category>
74Category category(_Category) {
75    return UNKNOWN;
76}
77
78template<>
79Category
80category<std::input_iterator_tag>(std::input_iterator_tag) {
81    return INPUT;
82}
83
84template<>
85Category
86category<std::forward_iterator_tag>(std::forward_iterator_tag) {
87    return FORWARD;
88}
89
90template<>
91Category
92category<std::bidirectional_iterator_tag>(std::bidirectional_iterator_tag) {
93    return BIDIRECTIONAL;
94}
95
96template<>
97Category
98category<std::random_access_iterator_tag>(std::random_access_iterator_tag) {
99    return RANDOM;
100}
101
102// Check if the custom method to get the category works as expected.
103bool testCategory()
104{
105    EXPECT_TRUE(category(android::iterator_category(Input())) == INPUT);
106    EXPECT_TRUE(category(android::iterator_category(Forward())) == FORWARD);
107    EXPECT_TRUE(category(android::iterator_category(Bidirectional())) == BIDIRECTIONAL);
108    EXPECT_TRUE(category(android::iterator_category(Random())) == RANDOM);
109    return true;
110}
111
112typedef std::__wrapper_iterator<int *, int *> WrapperIterator;
113
114// Check we can distinguish wrapper iterators.
115bool testWrapperIterator()
116{
117    EXPECT_FALSE(android::is_wrapper_iterator<android::Random>::value);
118    EXPECT_TRUE(android::is_wrapper_iterator<android::WrapperIterator>::value);
119    return true;
120}
121
122}  // namespace android
123
124int main(int argc, char **argv)
125{
126    FAIL_UNLESS(testCategory);
127    FAIL_UNLESS(testWrapperIterator);
128    return kPassed;
129}
130