generic stack with a static array

Pages: 12
No, it's a friend function (somewhere up there in the class definition).
This compiled and linked for me. The friend declaration was wrong and I used consistent typenames throughout the operator<< declarations.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
template<class StackItem,int StackSize>
class Stack
{
      friend std::ostream& operator<<(std::ostream & , const Stack<StackItem, StackSize>&);  
      private:
             StackItem Items[StackSize];
             int Top;
      public:
             Stack(){Top=0;}
             void Push(StackItem);
             void Pop(StackItem &);
             StackItem TopItem();
             bool IsEmpty(){return (Top==0);}
             bool IsFull () {return (Top==StackSize);}
             void clear();
             ~Stack();
};

template<class StackItem,int StackSize>
void Stack<StackItem,StackSize>::Push(StackItem x)
{
     Items[Top]=x;
     Top++;
}
template<class StackItem,int StackSize>
void Stack<StackItem,StackSize>::Pop(StackItem &x)
{
     x=Items[Top-1];
     Top--;
}
template<class StackItem,int StackSize>
StackItem Stack<StackItem,StackSize>::TopItem()
{
          return (Items[Top-1]);
}
template <class StackItem,int StackSize>
void Stack<StackItem,StackSize>::clear()
{
     Top=0;
}
template<class StackItem,int StackSize>
Stack<StackItem,StackSize>::~Stack()
{
   delete []Items;
}
template <class StackItem, int StackSize> 
std::ostream& operator<<(std::ostream &output,const Stack<StackItem,StackSize> &s)
{          
           for(int i = 0; i < s.Top; i++)
                   output << s.Items[i] << "|";
           return output;
}

int main()
{
    Stack<int,100>i;
    
    int a;
    int x;
    i.Push(1);
    i.Push(2);
    i.Push(3);
    i.Push(4);
    i.Push(5);
    
    std::cout<<i<<std::endl;
    
    a=i.TopItem();
    std::cout<<"The top item is "<<a<<std::endl;
    
    i.Pop(x);
    
    std::cout<<i<<std::endl;
    
    if(i.IsEmpty())
    {
         std::cout<<"Stack is empty"<<std::endl;
    }
    else
    {
        std::cout<<"Stack is not empty"<<std::endl;
    }
    
    if(i.IsFull())
    {
         std::cout<<"Stack is full"<<std::endl;
    }
    else
    {
        std::cout<<"Stack is not full"<<std::endl;
    }
    
    system ("pause");
    return 0;
    
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
template<class StackItem,int StackSize>
class Stack
{
      friend std::ostream& operator<<(std::ostream & , const Stack<StackItem, StackSize>&);  
      private:
             StackItem Items[StackSize];
             int Top;
      public:
             Stack(){Top=0;}
             void Push(StackItem);
             void Pop(StackItem &);
             StackItem TopItem();
             bool IsEmpty(){return (Top==0);}
             bool IsFull () {return (Top==StackSize);}
             void clear();
             ~Stack();
};

template<class StackItem,int StackSize>
void Stack<StackItem,StackSize>::Push(StackItem x)
{
     Items[Top]=x;
     Top++;
}
template<class StackItem,int StackSize>
void Stack<StackItem,StackSize>::Pop(StackItem &x)
{
     x=Items[Top-1];
     Top--;
}
template<class StackItem,int StackSize>
StackItem Stack<StackItem,StackSize>::TopItem()
{
          return (Items[Top-1]);
}
template <class StackItem,int StackSize>
void Stack<StackItem,StackSize>::clear()
{
     Top=0;
}
template<class StackItem,int StackSize>
Stack<StackItem,StackSize>::~Stack()
{
   delete []Items;
}
template <class StackItem, int StackSize> 
std::ostream& operator<<(std::ostream &output,const Stack<StackItem,StackSize> &s)
{          
           for(int i = 0; i < s.Top; i++)
                   output << s.Items[i] << "|";
           return output;
}

int main()
{
    Stack<int,100>i;
    
    int a;
    int x;
    i.Push(1);
    i.Push(2);
    i.Push(3);
    i.Push(4);
    i.Push(5);
    
    std::cout<<i<<std::endl;
    
    a=i.TopItem();
    std::cout<<"The top item is "<<a<<std::endl;
    
    i.Pop(x);
    
    std::cout<<i<<std::endl;
    
    if(i.IsEmpty())
    {
         std::cout<<"Stack is empty"<<std::endl;
    }
    else
    {
        std::cout<<"Stack is not empty"<<std::endl;
    }
    
    if(i.IsFull())
    {
         std::cout<<"Stack is full"<<std::endl;
    }
    else
    {
        std::cout<<"Stack is not full"<<std::endl;
    }
    
    system ("pause");
    return 0;
    
}


did you put all of this in one file,because i need to have them seperately.
Last edited on
Im getting no more compling errors,but now im having linking errors.

example
[Linker error] undefined reference to `Stack<int, 100>::Push(int)'
[Linker error] undefined reference to `operator<<(std::ostream&, Stack<int, 100> const&)'

header:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#ifndef S_Stack_h_
#define S_Stack_h_
#include <iostream>
template<class StackItem,int StackSize>
class Stack
{     
      template <class StackItem, int StackSize>
      friend std::ostream& operator<<(std::ostream & , const Stack<StackItem,StackSize> &);  
      private:
             StackItem Items[StackSize];
             int Top;
      public:
             Stack(){Top=0;}
             void Push(StackItem);
             void Pop(StackItem &);
             StackItem TopItem();
             bool IsEmpty(){return (Top==0);}
             bool IsFull () {return (Top==StackSize);}
             void clear();
             ~Stack();
};
#endif 




implementation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include "S_Stack.h"
#include<iostream>


template<class StackItem,int StackSize>
void Stack<StackItem,StackSize>::Push(StackItem x)
{
     Items[Top]=x;
     Top++;
}
template<class StackItem,int StackSize>
void Stack<StackItem,StackSize>::Pop(StackItem &x)
{
     x=Items[Top-1];
     Top--;
}
template<class StackItem,int StackSize>
StackItem Stack<StackItem,StackSize>::TopItem()
{
          return (Items[Top-1]);
}
template <class StackItem,int StackSize>
void Stack<StackItem,StackSize>::clear()
{
     Top=0;
}
template<class StackItem,int StackSize>
Stack<StackItem,StackSize>::~Stack()
{
   delete []Items;
}
template <class StackItem,int StackSize> 
std::ostream& operator<< (std::ostream &output,const Stack<StackItem,StackSize> &s)
{        
           for(int i=0; i< s.Top; i++)
                   output<<s.Items[i]<<"|";
           return output;

}


main:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#include "S_Stack.h"
#include<iostream>

int main()
{
    Stack<int,100>i;
    
    int a;
    int x;
    i.Push(1);
    std::cout<<i<<std::endl;
    i.Push(2);
    std::cout<<i<<std::endl;
    i.Push(3);
    std::cout<<i<<std::endl;
    i.Push(4);
    std::cout<<i<<std::endl;
    i.Push(5);
    std::cout<<i<<std::endl;
    
    
    a=i.TopItem();
    std::cout<<"The top item is "<<a<<std::endl;

    
    i.Pop(x);
    
    std::cout<<i<<std::endl;
    
    if(i.IsEmpty())
    {
         std::cout<<"Stack is empty"<<std::endl;
    }
    else
    {
        std::cout<<"Stack is not empty"<<std::endl;
    }
    
    if(i.IsFull())
    {
         std::cout<<"Stack is full"<<std::endl;
    }
    else
    {
        std::cout<<"Stack is not full"<<std::endl;
    }

    
    i.clear();
    std::cout<<i<<std::endl;
    if(i.IsEmpty())
    {
         std::cout<<"Stack is empty"<<std::endl;
    }
    else
    {
        std::cout<<"Stack is not empty"<<std::endl;
    }
    
    
    system ("pause");
    return 0;
    
}


any help is appreciated
would it be something wrong with my friend class function or something else?
Implementations of template methods/classes must be in the header file, not a separate .cpp file.
unfortunately i need it in the cpp file.any suggestions?
Why do you need it in the .cpp file?

Although it is possible, typically it is not done that way.

To do it, in the .cpp file you need to explicitly instantiate the template on all
types that your program will use.
im trying to do that,unfortunately im getting errors.

42 E:\373\S_Stack.cpp missing `>' to terminate the template argument list
42 E:\373\S_Stack.cpp template argument 2 is invalid
42 E:\373\S_Stack.cpp ISO C++ forbids declaration of `StackSize' with no type
42 E:\373\S_Stack.cpp explicit instantiation of non-template `int StackSize'
42 E:\373\S_Stack.cpp expected `;' before '>' token
43 E:\373\S_Stack.cpp missing `>' to terminate the template argument list
43 E:\373\S_Stack.cpp template argument 2 is invalid
43 E:\373\S_Stack.cpp expected `,' or `...' before '>' token
43 E:\373\S_Stack.cpp ISO C++ forbids declaration of `StackSize' with no type
43 E:\373\S_Stack.cpp template-id `operator<< <>' for `std::ostream& operator<<(std::ostream&, int)' does not match any template declaration

header:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#ifndef S_Stack_h_
#define S_Stack_h_
#include <iostream>

template<class StackItem,int StackSize>
class Stack
{     
      template <class t>
      friend std::ostream& operator<<(std::ostream & , const Stack<t,StackSize> &);  
      private:
             StackItem Items[StackSize];
             int Top;
      public:
             Stack(){Top=0;}
             void Push(StackItem);
             void Pop(StackItem &);
             StackItem TopItem();
             bool IsEmpty(){return (Top==0);};
             bool IsFull () {return (Top==StackSize);};
             void clear();
             ~Stack();
};
#endif 


implementation:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include "S_Stack.h"
#include<iostream>
using namespace std;


template<class StackItem,int StackSize>
void Stack<StackItem,StackSize>::Push(StackItem x)
{
     Items[Top]=x;
     Top++;
}
template<class StackItem,int StackSize>
void Stack<StackItem,StackSize>::Pop(StackItem &x)
{
     x=Items[Top-1];
     Top--;
}
template<class StackItem,int StackSize>
StackItem Stack<StackItem,StackSize>::TopItem()
{
          return (Items[Top-1]);
}
template <class StackItem,int StackSize>
void Stack<StackItem,StackSize>::clear()
{
     Top=0;
}
template<class StackItem,int StackSize>
Stack<StackItem,StackSize>::~Stack()
{
   delete []Items;
}
template <class t,int StackSize> 
ostream& operator<< (ostream &output,const Stack<t,StackSize> &s)
{        
           for(int i=0; i< s.Top; i++)
                   output<<s.Items[i]<<"|";
           return output;

}
 
template class Stack<int,int StackSize>;
template ostream& operator<< (ostream &output, Stack<int,int StackSize> const&s);


main:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include "S_Stack.h"
#include<iostream>
using namespace std;

int main()
{
    Stack<int,100>i;
    
    int a;
    int x;
    i.Push(1);
   cout<<i<<endl;
    i.Push(2);
    cout<<i<<endl;
    i.Push(3);
    cout<<i<<endl;
    i.Push(4);
    cout<<i<<endl;
    i.Push(5);
   cout<<i<<endl;
    
    
    a=i.TopItem();
    cout<<"The top item is "<<a<<endl;

    
    i.Pop(x);
    
    cout<<x<<endl;
    
    if(i.IsEmpty())
    {
         cout<<"Stack is empty"<<endl;
    }
    else
    {
        cout<<"Stack is not empty"<<endl;
    }
    
    if(i.IsFull())
    {
         cout<<"Stack is full"<<endl;
    }
    else
    {
        cout<<"Stack is not full"<<endl;
    }

    
    i.clear();
   cout<<i<<endl;
    if(i.IsEmpty())
    {
         cout<<"Stack is empty"<<endl;
    }
    else
    {
        cout<<"Stack is not empty"<<endl;
    }

    
    
    system ("pause");
    return 0;
    
}


i know this method works because ive used it for other programs.Its just the second variable is whats throwing me.please,i really need help with this as soon as possible.
This isn't enough:

 
template class Stack<int,int StackSize>;


First of all, it's a syntax error, but secondly, even if you correct the syntax error (a bit of work), it's still
a template, just only on the size.

You quite literally have to do this:

1
2
template<> class Stack<int, 10>;  // stack of 10 ints
template<> class Stack<int, 100>;  // stack of 100 ints 


etc.
It works.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#include <iostream>

template<class StackItem,int StackSize>
class Stack
{     
	template <class t>
	friend std::ostream& operator<<(std::ostream & , const Stack<t,StackSize> &);  

private:
	StackItem Items[StackSize];
	int Top;

public:
	Stack()			{Top=0;}
	void Push(StackItem);
	void Pop(StackItem &);
	StackItem TopItem();
	bool IsEmpty()	{return (Top==0);}
	bool IsFull ()	{return (Top==StackSize);}
	void clear();
	~Stack();
};

//---------------------------------------------------------------------------

template<class StackItem,int StackSize>
void Stack<StackItem,StackSize>::Push(StackItem x)
{
	Items[Top]=x;
	Top++;
}

template<class StackItem,int StackSize>
void Stack<StackItem,StackSize>::Pop(StackItem &x)
{
	x=Items[Top-1];
	Top--;
}

template<class StackItem,int StackSize>
StackItem Stack<StackItem,StackSize>::TopItem()
{
	return Items[Top-1];
}

template <class StackItem,int StackSize>
void Stack<StackItem,StackSize>::clear()
{
	Top = 0;
}

template<class StackItem,int StackSize>
Stack<StackItem,StackSize>::~Stack()
{
//	delete []Items;
}

template <class t,int StackSize> 
std::ostream& operator<<(std::ostream &output, const Stack<t, StackSize> &s)
{        
	for (int i = 0; i < s.Top; i++)
		output << s.Items[i] << "|";

	return output;
}

//template class Stack<int,int StackSize>;
//template ostream& operator<< (ostream &output, Stack<int,int StackSize> const&s);

//---------------------------------------------------------------------------

int main()
{
	Stack<int,100> i;
	int a;
	int x;
	i.Push(1);
	std::cout << i << std::endl;

	i.Push(2);
	std::cout << i << std::endl;

	i.Push(3);
	std::cout << i << std::endl;

	i.Push(4);
	std::cout << i << std::endl;

	i.Push(5);
	std::cout << i << std::endl;

	a = i.TopItem();
	std::cout << "The top item is " << a << std::endl;

	i.Pop(x);
	std::cout << x << std::endl;

	if(i.IsEmpty())
	{
		std::cout << "Stack is empty" << std::endl;
	}
	else
	{
		std::cout << "Stack is not empty" << std::endl;
	}

	if(i.IsFull())
	{
		std::cout << "Stack is full" << std::endl;
	}
	else
	{
		std::cout << "Stack is not full" << std::endl;
	}

	i.clear();
	std::cout << i << std::endl;

	if(i.IsEmpty())
	{
		std::cout << "Stack is empty" << std::endl;
	}
	else
	{
		std::cout << "Stack is not empty" << std::endl;
	}

	return 0;
}
ok,got it mostly done just this last group of errors
In instantiation of `std::ostream& operator<<(std::ostream&, const Stack<t, StackSize>&) [with t = int, StackItem = int, int StackSize = 100]':
43 E:\373\S_Stack.cpp instantiated from here
43 E:\373\S_Stack.cpp explicit instantiation of `std::ostream& operator<<(std::ostream&, const Stack<t, StackSize>&) [with t = int, StackItem = int, int StackSize = 100]' but no definition available
43 E:\373\S_Stack.cpp In instantiation of `std::ostream& operator<<(std::ostream&, const Stack<t, StackSize>&) [with t = int, StackItem = int, int StackSize = 100]':
43 E:\373\S_Stack.cpp instantiated from here
43 E:\373\S_Stack.cpp explicit instantiation of `std::ostream& operator<<(std::ostream&, const Stack<t, StackSize>&) [with t = int, StackItem = int, int StackSize = 100]' but no definition available
43 E:\373\S_Stack.cpp instantiated from here
43 E:\373\S_Stack.cpp explicit instantiation of `std::ostream& operator<<(std::ostream&, const Stack<t, StackSize>&) [with t = int, StackItem = int, int StackSize = 100]' but no definition available

header:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#ifndef S_Stack_h_
#define S_Stack_h_
#include <iostream>

template<class StackItem,int StackSize>
class Stack
{     
      template <class t>
      friend std::ostream& operator<<(std::ostream & , const Stack<t,StackSize> &);  
      private:
             StackItem Items[StackSize];
             int Top;
      public:
             Stack(){Top=0;}
             void Push(StackItem);
             void Pop(StackItem &);
             StackItem TopItem();
             bool IsEmpty(){return (Top==0);};
             bool IsFull () {return (Top==StackSize);};
             void clear();
             ~Stack();
};
#endif 


implementation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include "S_Stack.h"
#include<iostream>

template<class StackItem,int StackSize>
void Stack<StackItem,StackSize>::Push(StackItem x)
{
     Items[Top]=x;
     Top++;
}
template<class StackItem,int StackSize>
void Stack<StackItem,StackSize>::Pop(StackItem &x)
{
     x=Items[Top-1];
     Top--;
}
template<class StackItem,int StackSize>
StackItem Stack<StackItem,StackSize>::TopItem()
{
          return (Items[Top-1]);
}
template <class StackItem,int StackSize>
void Stack<StackItem,StackSize>::clear()
{
     Top=0;
}
template<class StackItem,int StackSize>
Stack<StackItem,StackSize>::~Stack()
{
   delete []Items;
}
template <class t,int StackSize> 
std::ostream& operator<< (std::ostream &output,const Stack<t,StackSize> &s)
{        
           for(int i=0; i< s.Top; i++)
                   output<<s.Items[i]<<"|";
           return output;

}
 
template class Stack<int,100>;
template std::ostream& operator<< (std::ostream &output, Stack<int,100> const&s);


main:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include "S_Stack.h"
#include<iostream>


int main()
{
    Stack<int,100>i;
    
    int a;
    int x;
    i.Push(1);
   std::cout<<i<<std::endl;
    i.Push(2);
    std::cout<<i<<std::endl;
    i.Push(3);
    std::cout<<i<<std::endl;
    i.Push(4);
    std::cout<<i<<std::endl;
    i.Push(5);
   std::cout<<i<<std::endl;
    
    
    a=i.TopItem();
    std::cout<<"The top item is "<<a<<std::endl;

    
    i.Pop(x);
    
    std::cout<<x<<std::endl;
    
    if(i.IsEmpty())
    {
         std::cout<<"Stack is empty"<<std::endl;
    }
    else
    {
        std::cout<<"Stack is not empty"<<std::endl;
    }
    
    if(i.IsFull())
    {
         std::cout<<"Stack is full"<<std::endl;
    }
    else
    {
        std::cout<<"Stack is not full"<<std::endl;
    }

    
    i.clear();
   std::cout<<i<<std::endl;
    if(i.IsEmpty())
    {
         std::cout<<"Stack is empty"<<std::endl;
    }
    else
    {
        std::cout<<"Stack is not empty"<<std::endl;
    }

    
    
    system ("pause");
    return 0;
    
}


any help is appreciated.
I've posted code that works, commenting out the problem code. Why aren't you using it?
cause i get linker errors

[Linker error] undefined reference to `std::ostream& operator<< <int>(std::ostream&, Stack<int, 100> const&)'

and i need it in more than one file.
Last edited on
heres what i have

implementation:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include "S_Stack.h"
#include<iostream>

template<class StackItem,int StackSize>
void Stack<StackItem,StackSize>::Push(StackItem x)
{
     Items[Top]=x;
     Top++;
}
template<class StackItem,int StackSize>
void Stack<StackItem,StackSize>::Pop(StackItem &x)
{
     x=Items[Top-1];
     Top--;
}
template<class StackItem,int StackSize>
StackItem Stack<StackItem,StackSize>::TopItem()
{
          return (Items[Top-1]);
}
template <class StackItem,int StackSize>
void Stack<StackItem,StackSize>::clear()
{
     Top=0;
}
template<class StackItem,int StackSize>
Stack<StackItem,StackSize>::~Stack()
{
   //delete []Items;
}
template <class t,int StackSize> 
std::ostream& operator<< (std::ostream &output, Stack<t,StackSize> const &s)
{        
           for(int i=0; i< s.Top; i++)
                   output<<s.Items[i]<<"|";
           return output;

}
 
template class Stack<int,100>;
template std::ostream& operator<< (std::ostream &output,Stack<int,100> const&s);


header:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#ifndef S_Stack_h_
#define S_Stack_h_
#include <iostream>

template<class StackItem,int StackSize>
class Stack
{     
      template <class t>
      friend std::ostream& operator<<(std::ostream & ,  Stack<t,StackSize> const &);  
      private:
             StackItem Items[StackSize];
             int Top;
      public:
             Stack(){Top=0;}
             void Push(StackItem);
             void Pop(StackItem &);
             StackItem TopItem();
             bool IsEmpty(){return (Top==0);};
             bool IsFull () {return (Top==StackSize);};
             void clear();
             ~Stack();
};
#endif 
What compiler did you use? I reformatted, compiled and ran it thru a debugger. I think you've wasted my time.
dev
Topic archived. No new replies allowed.
Pages: 12