Skip to content
Fetching contributors…
Cannot retrieve contributors at this time
137 lines (121 sloc) 3.87 KB
/*
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010- Facebook, Inc. (http://www.facebook.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
*/
#ifndef RANGE_H_
#define RANGE_H_
#include <util/meta.h>
namespace HPHP {
/**
* DefaultRangePolicy --
* MappedRangePolicy --
* KeyRangePolicy --
*
* Parameters to Range<...>.
*
* Type functions for pulling values out of types. Both a compile-time
* function providing the type value_type, and a runtime function extract().
*/
template<typename Iter>
struct DefaultRangePolicy {
typedef typename match_iterator<
Iter,
typename std::iterator_traits<Iter>::value_type
>::type value_type;
static value_type& extract(const Iter& i) {
return *i;
}
};
template<typename Iter>
struct MappedRangePolicy {
typedef typename match_iterator<
Iter,
typename Iter::value_type::second_type
>::type value_type;
static value_type& extract(const Iter& i) {
return i->second;
}
};
template<typename Iter>
struct KeyRangePolicy {
// The keys in a map cannot be mutable.
typedef typename boost::add_const<typename Iter::value_type::first_type
>::type value_type;
value_type& extract(const Iter& i) {
return i->first;
}
};
/**
* IterRange --
*
* A Range encapsulating forward iteration over typical iterators,
* including pointers.
*
* You can control mutability and the iterator type, and the mapping from
* iterators to range values, via It and RangePolicy. Mutation
* happens in the underlying containers, assuming well-behaved iterators.
*
* E.g., mutable range of ints:
* Range<vector<int>::iterator> rng;
*
* Immutable range of the ints in a string->int map:
* typedef map<string, int> SIMap;
* Range<SIMap::const_iterator, MappedRangePolicy> rng;
*/
template<typename Iter,
template<typename> class RangePolicy = DefaultRangePolicy>
class IterRange {
typedef RangePolicy<Iter> Extractor;
public:
typedef typename Extractor::value_type value_type;
IterRange(const Iter& begin, const Iter& end) :
m_next(begin), m_end(end) {}
IterRange(const IterRange& r) :
m_next(r.m_next), m_end(r.m_end) {}
IterRange& operator=(const IterRange& r) {
m_next = r.m_next;
m_end = r.m_end;
return *this;
}
value_type& front() const {
return Extractor::extract(m_next);
}
value_type& popFront() {
value_type& tmp = front();
m_next++;
return tmp;
}
bool empty() const { return m_next == m_end; }
private:
Iter m_next, m_end;
};
/**
* Range --
*
* A range that spans an STL-like container. Just adds a convenience constructor
* for begin()/end() ranges.
*/
template<typename Cont,
typename It = typename Cont::const_iterator,
template<typename> class RangePolicy = DefaultRangePolicy>
struct Range : public IterRange<It, RangePolicy> {
explicit Range(typename match_iterator<It, Cont>::type& c) :
IterRange<It, RangePolicy>(c.begin(), c.end()) { }
};
template<typename Range, typename Function>
void range_foreach(Range r, const Function& f) {
while (!r.empty()) f(r.popFront());
}
}
#endif /* RANGE_H_ */
Jump to Line
Something went wrong with that request. Please try again.