Files
swift-mirror/include/swift/Basic/STLExtras.h
Joe Groff 9f12e2e4a4 Enable same-type concrete constraints, e.g. <T: P where T.Assoc == Int>
Let ArchetypeType nested types and PotentialArchetypes be bound to concrete types in addition to archetypes. Constraints to outer context archetypes still suffer type-checker issues, but constraints to true concrete types should work now.

Swift SVN r14832
2014-03-08 17:18:17 +00:00

126 lines
3.7 KiB
C++

//===- STLExtras.h - additions to the STL -----------------------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
/// \file Provides STL-style algorithms for convenience.
//
//===----------------------------------------------------------------------===//
#ifndef SWIFT_BASIC_INTERLEAVE_H
#define SWIFT_BASIC_INTERLEAVE_H
#include <functional>
#include <cassert>
namespace swift {
/// @{
/// An STL-style algorithm similar to std::for_each that applies a second
/// functor between every pair of elements.
///
/// This provides the control flow logic to, for example, print a
/// comma-separated list:
/// \code
/// interleave(names.begin(), names.end(),
/// [&](StringRef name) { OS << name; },
/// [&] { OS << ", "; });
/// \endcode
template <typename ForwardIterator, typename UnaryFunctor,
typename NullaryFunctor>
inline void interleave(ForwardIterator begin, ForwardIterator end,
UnaryFunctor each_fn,
NullaryFunctor between_fn) {
if (begin == end)
return;
each_fn(*begin);
++begin;
for (; begin != end; ++begin) {
between_fn();
each_fn(*begin);
}
}
template <typename Container, typename UnaryFunctor, typename NullaryFunctor>
inline void interleave(const Container &c, UnaryFunctor each_fn,
NullaryFunctor between_fn) {
interleave(c.begin(), c.end(), each_fn, between_fn);
}
/// @}
/// @{
/// The equivalent of std::for_each, but for two lists at once.
template <typename InputIt1, typename InputIt2, typename BinaryFunction>
inline void for_each(InputIt1 I1, InputIt1 E1, InputIt2 I2, BinaryFunction f) {
while (I1 != E1) {
f(*I1, *I2);
++I1; ++I2;
}
}
template <typename Container1, typename Container2, typename BinaryFunction>
inline void for_each(const Container1 &c1, const Container2 &c2,
BinaryFunction f) {
assert(c1.size() == c2.size());
for_each(c1.begin(), c1.end(), c2.begin(), f);
}
/// The equivalent of std::for_each, but for three lists at once.
template <typename InputIt1, typename InputIt2, typename InputIt3,
typename TernaryFunction>
inline void for_each3(InputIt1 I1, InputIt1 E1, InputIt2 I2, InputIt3 I3,
TernaryFunction f) {
while (I1 != E1) {
f(*I1, *I2, *I3);
++I1; ++I2; ++I3;
}
}
template <typename Container1, typename Container2, typename Container3,
typename TernaryFunction>
inline void for_each3(const Container1 &c1, const Container2 &c2,
const Container3 &c3,
TernaryFunction f) {
assert(c1.size() == c2.size());
assert(c2.size() == c3.size());
for_each3(c1.begin(), c1.end(), c2.begin(), c3.begin(), f);
}
/// @}
/// @{
/// Declares a member \c type that is a std::function compatible with the given
/// callable type.
///
/// \tparam T A callable type, such as a lambda.
template <typename T>
struct as_function : public as_function<decltype(&T::operator())> {};
template <typename L, typename R, typename... Args>
struct as_function<R(L::*)(Args...) const> {
using type = std::function<R(Args...)>;
};
/// @}
/// Returns a std::function that can call a lambda without copying it.
template <typename L>
static typename as_function<L>::type makeStackLambda(const L &theLambda) {
return std::cref(theLambda);
}
} // end namespace swift
#endif