On-line Guides
All Guides
eBook Store
iOS / Android
Linux for Beginners
Office Productivity
Linux Installation
Linux Security
Linux Utilities
Linux Virtualization
Linux Kernel
Programming
Scripting Languages
Development Tools
Web Development
GUI Toolkits/Desktop
Databases
Mail Systems
openSolaris
Eclipse Documentation
Techotopia.com
Virtuatopia.com

How To Guides
Virtualization
Linux Security
Linux Filesystems
Web Servers
Graphics & Desktop
PC Hardware
Windows
Problem Solutions

Thinking in C++ Vol 2 - Practical Programming
Prev Home Next

Adapter takes one type and produces an interface to some other type. This is useful when you re given a library or piece of code that has a particular interface, and you ve got a second library or piece of code that uses the same basic ideas as the first piece, but expresses itself differently. If you adapt the forms of expression to each other, you can rapidly produce a solution.

Suppose you have a generator class that produces Fibonacci numbers:

//: C10:FibonacciGenerator.h
#ifndef FIBONACCIGENERATOR_H
#define FIBONACCIGENERATOR_H

class FibonacciGenerator {
int n;
int val[2];
public:
FibonacciGenerator() : n(0) { val[0] = val[1] = 0; }
int operator()() {
int result = n > 2 ? val[0] + val[1] : n > 0 ? 1 : 0;
++n;
val[0] = val[1];
val[1] = result;
return result;
}
int count() { return n; }
};
#endif // FIBONACCIGENERATOR_H ///:~

Since it s a generator, you use it by calling the operator( ), like this:

//: C10:FibonacciGeneratorTest.cpp
#include <iostream>
#include "FibonacciGenerator.h"
using namespace std;

int main() {
FibonacciGenerator f;
for(int i =0; i < 20; i++)
cout << f.count() << ": " << f() << endl;
} ///:~

Perhaps you would like to take this generator and perform STL numeric algorithm operations with it. Unfortunately, the STL algorithms only work with iterators, so you have an interface mismatch. The solution is to create an adapter that will take the FibonacciGenerator and produce an iterator for the STL algorithms to use. Since the numeric algorithms only require an input iterator, the Adapter is fairly straightforward (for something that produces an STL iterator, that is):

#include <iostream>
#include <numeric>
#include "FibonacciGenerator.h"
#include "../C06/PrintSequence.h"
using namespace std;

class FibonacciAdapter { // Produce an iterator
FibonacciGenerator f;
int length;
public:
class iterator;
friend class iterator;
class iterator : public std::iterator<
public:
typedef int value_type;
bool operator==(const iterator&) const {
return ap.f.count() == ap.length;
}
bool operator!=(const iterator& x) const {
return !(*this == x);
}
int operator*() const { return ap.f(); }
iterator& operator++() { return *this; }
iterator operator++(int) { return *this; }
};
iterator begin() { return iterator(*this); }
iterator end() { return iterator(*this); }
};

int main() {
const int SZ = 20;
cout << "accumulate: "
<< accumulate(a1.begin(), a1.end(), 0) << endl;
cout << "inner product: "
<< inner_product(a2.begin(), a2.end(), a3.begin(), 0)
<< endl;
int r1[SZ] = {0};
int* end = partial_sum(a4.begin(), a4.end(), r1);
print(r1, end, "partial_sum", " ");
int r2[SZ] = {0};