SFINAEで実装したSTLアルゴリズムです
これを使うと以下のように書けます
vector<int> v; sort(v); // begin/endではなくコンテナ/配列を直接渡す
ソースは以下(※めっちゃ長い)
// SFINAEをサポートしているコンパイラか? #if !defined(_MSC_VER) || (_MSC_VER > 1300) // 1300 == VC++ 7.0 #define SHAND_SUPPORT_SFINAE #endif namespace shand { #ifdef SHAND_SUPPORT_SFINAE namespace algorithm_detail { // STL Container struct sfinae_types { typedef char yes; typedef struct { char arr[2]; } no; }; template <class Type> struct is_stl : sfinae_types { private: template <class Type> static yes check(typename Type::iterator*); template<class> static no check(...); public: enum { value = sizeof(yes)==sizeof(check<Type>(0)) }; }; // enable_if template <bool, class Type = void> struct enable_if_c { typedef Type type; }; template <class Type> struct enable_if_c<false, Type> {}; template <class Cond, class Type = void> struct enable_if : public enable_if_c<Cond::value, Type> {}; } // namespace shand::algorithm_detail #define IS_STL(Container) typename algorithm_detail::enable_if<algorithm_detail::is_stl<Container> >::type* = 0 #endif // SHAND_SUPPORT_SFINAE #ifdef SHAND_SUPPORT_SFINAE // for_each template <class Type, int Size, class Predicate> inline Predicate for_each(Type (&ar)[Size], Predicate pred, void* = 0) { return std::for_each(ar, ar + Size, pred); } template <class Container, class Predicate> inline Predicate for_each(Container &container, Predicate pred, IS_STL(Container)) { return std::for_each(container.begin(), container.end(), pred); } template <class Container, class Predicate> inline Predicate for_each(const Container &container, Predicate pred, IS_STL(Container)) { return std::for_each(container.begin(), container.end(), pred); } // find template <class Type, int Size, class Target> inline Type* find(Type (&ar)[Size], const Target& value, void* = 0) { return std::find(ar, ar + Size, value); } template <class Container, class Target> inline typename Container::iterator find(Container &container, const Target& value, IS_STL(Container)) { return std::find(container.begin(), container.end(), value); } template <class Container, class Target> inline typename Container::const_iterator find(const Container &container, const Target& value, IS_STL(Container)) { return std::find(container.begin(), container.end(), value); } // find_if template <class Type, int Size, class Predicate> inline Type* find_if(Type (&ar)[Size], Predicate pred, void* = 0) { return std::find_if(ar, ar + Size, pred); } template <class Container, class Predicate> inline typename Container::iterator find_if(Container& container, Predicate pred, IS_STL(Container)) { return std::find_if(container.begin(), container.end(), pred); } template <class Container, class Predicate> inline typename Container::const_iterator find_if(const Container& container, Predicate pred, IS_STL(Container)) { return std::find_if(container.begin(), container.end(), pred); } // find_first_of template <class LType, int LSize, class RType, int RSize> inline LType* find_first_of(LType (&lhs)[LSize], RType (&rhs)[RSize], void* = 0) { return std::find_first_of(lhs, lhs + LSize, rhs, rhs + RSize); } template <class LType, int LSize, class RType, int RSize, class Predicate> inline LType* find_first_of(LType (&lhs)[LSize], RType (&rhs)[RSize], Predicate pred, void* = 0) { return std::find_first_of(lhs, lhs + LSize, rhs, rhs + RSize, pred); } template <class LContainer, class RContainer> inline typename LContainer::iterator find_first_of(LContainer &lhs, RContainer &rhs, IS_STL(LContainer)) { return std::find_first_of(lhs.begin(), lhs.end(), rhs.begin(), rhs.end()); } template <class LContainer, class RContainer, class Predicate> inline typename LContainer::iterator find_first_of(LContainer &lhs, RContainer &rhs, Predicate pred, IS_STL(LContainer)) { return std::find_first_of(lhs.begin(), lhs.end(), rhs.begin(), rhs.end(), pred); } template <class LContainer, class RContainer> inline typename LContainer::const_iterator find_first_of(const LContainer& lhs, const RContainer& rhs, IS_STL(LContainer)) { return std::find_first_of(lhs.begin(), lhs.end(), rhs.begin(), rhs.end()); } template <class LContainer, class RContainer, class Predicate> inline typename LContainer::const_iterator find_first_of(const LContainer& lhs, const RContainer& rhs, Predicate pred, IS_STL(LContainer)) { return std::find_first_of(lhs.begin(), lhs.end(), rhs.begin(), rhs.end(), pred); } // find_end template <class LType, int LSize, class RType, int RSize> inline LType* find_end(LType (&lhs)[LSize], RType (&rhs)[RSize], void* = 0) { return std::find_end(lhs, lhs + LSize, rhs, rhs + RSize); } template <class LType, int LSize, class RType, int RSize, class Predicate> inline LType* find_end(LType (&lhs)[LSize], RType (&rhs)[RSize], Predicate pred, void* = 0) { return std::find_end(lhs, lhs + LSize, rhs, rhs + RSize, pred); } template <class LContainer, class RContainer> inline typename LContainer::iterator find_end(LContainer &lhs, RContainer &rhs, IS_STL(LContainer)) { return std::find_end(lhs.begin(), lhs.end(), rhs.begin(), rhs.end()); } template <class LContainer, class RContainer, class Predicate> inline typename LContainer::iterator find_end(LContainer &lhs, RContainer &rhs, Predicate pred, IS_STL(LContainer)) { return std::find_end(lhs.begin(), lhs.end(), rhs.begin(), rhs.end(), pred); } template <class LContainer, class RContainer> inline typename LContainer::const_iterator find_end(const LContainer& lhs, const RContainer& rhs, IS_STL(LContainer)) { return std::find_end(lhs.begin(), lhs.end(), rhs.begin(), rhs.end()); } template <class LContainer, class RContainer, class Predicate> inline typename LContainer::const_iterator find_end(const LContainer& lhs, const RContainer& rhs, Predicate pred, IS_STL(LContainer)) { return std::find_end(lhs.begin(), lhs.end(), rhs.begin(), rhs.end(), pred); } // adjacent_find template <class Type, int Size> inline Type* adjacent_find(Type (&ar)[Size], void* = 0) { return std::adjacent_find(ar, ar + Size); } template <class Type, int Size, class Predicate> inline Type* adjacent_find(Type (&ar)[Size], Predicate pred, void* = 0) { return std::adjacent_find(ar, ar + Size, pred); } template <class Container> inline typename Container::iterator adjacent_find(Container& container, IS_STL(Container)) { return std::adjacent_find(container.begin(), container.end()); } template <class Container> inline typename Container::const_iterator adjacent_find(const Container& container, IS_STL(Container)) { return std::adjacent_find(container.begin(), container.end()); } template <class Container, class Predicate> inline typename Container::iterator adjacent_find(Container& container, Predicate pred, IS_STL(Container)) { return std::adjacent_find(container.begin(), container.end(), pred); } template <class Container, class Predicate> inline typename Container::const_iterator adjacent_find(const Container& container, Predicate pred, IS_STL(Container)) { return std::adjacent_find(container.begin(), container.end(), pred); } // count template <class Type, int Size, class Target> inline Type count(Type (&ar)[Size], const Target& value, void* = 0) { return std::count(ar, ar + Size, value); } template <class Container, class Target> inline typename Container::difference_type count(const Container& container, const Target& value, IS_STL(Container)) { return std::count(container.begin(), container.end(), value); } // count_if template <class Type, int Size, class Predicate> inline Type count_if(Type (&ar)[Size], Predicate pred, void* = 0) { return std::count_if(ar, ar + Size, pred); } template <class Container, class Predicate> inline typename Container::difference_type count_if(const Container& container, Predicate pred, IS_STL(Container)) { return std::count_if(container.begin(), container.end(), pred); } // mismatch template <class Type, int Size, class InputIterator> inline std::pair<Type*, InputIterator> mismatch(Type (&ar)[Size], InputIterator first, void* = 0) { return std::mismatch(ar, ar + Size, first); } template <class Type, int Size, class InputIterator, class Predicate> inline std::pair<Type*, InputIterator> mismatch(Type (&ar)[Size], InputIterator first, Predicate pred, void* = 0) { return std::mismatch(ar, ar + Size, first, pred); } template <class Container, class InputIterator> inline std::pair<typename Container::iterator, InputIterator> mismatch(Container& container, InputIterator first, IS_STL(Container)) { return std::mismatch(container.begin(), container.end(), first); } template <class Container, class InputIterator, class Predicate> inline std::pair<typename Container::iterator, InputIterator> mismatch(Container& container, InputIterator first, Predicate pred, IS_STL(Container)) { return std::mismatch(container.begin(), container.end(), first, pred); } template <class Container, class InputIterator> inline std::pair<typename Container::const_iterator, InputIterator> mismatch(const Container& container, InputIterator first, IS_STL(Container)) { return std::mismatch(container.begin(), container.end(), first); } template <class Container, class InputIterator, class Predicate> inline std::pair<typename Container::const_iterator, InputIterator> mismatch(const Container& container, InputIterator first, Predicate pred, IS_STL(Container)) { return std::mismatch(container.begin(), container.end(), first, pred); } // equal template <class Type, int Size, class InputIterator> inline bool equal(Type (&ar)[Size], InputIterator first, void* = 0) { return std::equal(ar, ar + Size, first); } template <class Type, int Size, class InputIterator, class Predicate> inline bool equal(Type (&ar)[Size], InputIterator first, Predicate pred, void* = 0) { return std::equal(ar, ar + Size, first, pred); } template <class Container, class InputIterator> inline bool equal(const Container& container, InputIterator first, IS_STL(Container)) { return std::equal(container.begin(), container.end(), first); } template <class Container, class InputIterator, class Predicate> inline bool equal(const Container& container, InputIterator first, Predicate pred, IS_STL(Container)) { return std::equal(container.begin(), container.end(), first, pred); } // search template <class LType, int LSize, class RType, int RSize> inline LType* search(LType (&lhs)[LSize], RType (&rhs)[RSize], void* = 0) { return std::search(lhs, lhs + LSize, rhs, rhs + RSize); } template <class LType, int LSize, class RType, int RSize, class BynaryPredicate> inline LType* search(LType (&lhs)[LSize], RType (&rhs)[RSize], BynaryPredicate pred, void* = 0) { return std::search(lhs, lhs + LSize, rhs, rhs + RSize, pred); } template <class LContainer, class RContainer> inline typename LContainer::iterator search(LContainer& lhs, RContainer& rhs, IS_STL(LContainer)) { return std::search(lhs.begin(), lhs.end(), rhs.begin(), rhs.end()); } template <class LContainer, class RContainer, class BynaryPredicate> inline typename LContainer::iterator search(LContainer& lhs, RContainer& rhs, BynaryPredicate pred, IS_STL(LContainer)) { return std::search(lhs.begin(), lhs.end(), rhs.begin(), rhs.end(), pred); } template <class LContainer, class RContainer> inline typename LContainer::const_iterator search(const LContainer& lhs, const RContainer& rhs, IS_STL(LContainer)) { return std::search(lhs.begin(), lhs.end(), rhs.begin(), rhs.end()); } template <class LContainer, class RContainer, class BynaryPredicate> inline typename LContainer::const_iterator search(const LContainer& lhs, const RContainer& rhs, BynaryPredicate pred, IS_STL(LContainer)) { return std::search(lhs.begin(), lhs.end(), rhs.begin(), rhs.end(), pred); } // copy template <class Type, int Size, class OutputIterator> inline OutputIterator copy(Type (&ar)[Size], OutputIterator result, void* = 0) { return std::copy(ar, ar + Size, result); } template <class Container, class OutputIterator> inline OutputIterator copy(const Container& container, OutputIterator result, IS_STL(Container)) { return std::copy(container.begin(), container.end(), result); } // copy_backward template <class Type, int Size, class BidirectionalIterator> inline BidirectionalIterator copy_backward(Type (&ar)[Size], BidirectionalIterator result, void* = 0) { return std::copy_backward(ar, ar + Size, result); } template <class Container, class BidirectionalIterator> inline BidirectionalIterator copy_backward(const Container& container, BidirectionalIterator result, IS_STL(Container)) { return std::copy_backward(container.begin(), container.end(), result); } // transform template <class Type, int Size, class OutputIterator, class UnaryOperation> inline OutputIterator transform(Type (&ar)[Size], OutputIterator result, UnaryOperation op, void* = 0) { return std::transform(ar, ar + Size, result, op); } template <class Type, int Size, class InputIterator, class OutputIterator, class BynaryOperation> inline OutputIterator transform(Type (&ar)[Size], InputIterator first, OutputIterator result, BynaryOperation op, void* = 0) { return std::transform(ar, ar + Size, first, result, op); } template <class Container, class OutputIterator, class UnaryOperation> inline OutputIterator transform(const Container& container, OutputIterator result, UnaryOperation op, IS_STL(Container)) { return std::transform(container.begin(), container.end(), result, op); } template <class Container, class InputIterator, class OutputIterator, class BynaryOperation> inline OutputIterator transform(const Container& container, InputIterator first, OutputIterator result, BynaryOperation op, IS_STL(Container)) { return std::transform(container.begin(), container.end(), first, result, op); } // replace template <class Type, int Size, class Target> inline void replace(Type (&ar)[Size], const Target& old_value, const Target& new_value, void* = 0) { std::replace(ar, ar + Size, old_value, new_value); } template <class Container, class Target> inline void replace(Container& container, const Target& old_value, const Target& new_value, IS_STL(Container)) { std::replace(container.begin(), container.end(), old_value, new_value); } // replace_if template <class Type, int Size, class Predicate, class Target> inline void replace_if(Type (&ar)[Size], Predicate pred, const Target& new_value, void* = 0) { std::replace_if(ar, ar + Size, pred, new_value); } template <class Container, class Predicate, class Target> inline void replace_if(Container& container, Predicate pred, const Target& new_value, IS_STL(Container)) { std::replace_if(container.begin(), container.end(), pred, new_value); } // replace_copy template <class Type, int Size, class OutputIterator, class Target> inline OutputIterator replace_copy(Type (&ar)[Size], OutputIterator result, const Target& old_value, const Target& new_value, void* = 0) { return std::replace_copy(ar, ar + Size, result, old_value, new_value); } template <class Container, class OutputIterator, class Target> inline OutputIterator replace_copy(const Container& container, OutputIterator result, const Target& old_value, const Target& new_value, IS_STL(Container)) { return std::replace_copy(container.begin(), container.end(), result, old_value, new_value); } // replace_copy_if template <class Type, int Size, class OutputIterator, class Predicate, class Target> inline OutputIterator replace_copy_if(Type (&ar)[Size], OutputIterator result, Predicate pred, const Target& new_value, void* = 0) { return std::replace_copy_if(ar, ar + Size, result, pred, new_value); } template <class Container, class OutputIterator, class Predicate, class Target> inline OutputIterator replace_copy_if(const Container& container, OutputIterator result, Predicate pred, const Target& new_value, IS_STL(Container)) { return std::replace_copy_if(container.begin(), container.end(), result, pred, new_value); } // fill template <class Type, int Size, class Target> inline void fill(Type (&ar)[Size], const Target& value, void* = 0) { std::fill(ar, ar + Size, value); } template <class Container, class Target> inline void fill(Container& container, const Target& value, IS_STL(Container)) { std::fill(container.begin(), container.end(), value); } // generate template <class Type, int Size, class Generator> inline void generate(Type (&ar)[Size], Generator gen, void* = 0) { return std::generate(ar, ar + Size, gen); } template <class Container, class Generator> inline void generate(Container &container, Generator gen, IS_STL(Container)) { return std::generate(container.begin(), container.end(), gen); } // remove template <class Type, int Size, class Target> inline Type* remove(Type (&ar)[Size], const Target& value, void* = 0) { return std::remove(ar, ar + Size, value); } template <class Container, class Target> inline typename Container::iterator remove(Container& container, const Target& value, IS_STL(Container)) { return std::remove(container.begin(), container.end(), value); } // remove_if template <class Type, int Size, class Predicate> inline Type* remove_if(Type (&ar)[Size], Predicate pred, void* = 0) { return std::remove_if(ar, ar + Size, pred); } template <class Container, class Predicate> inline typename Container::iterator remove_if(Container& container, Predicate pred, IS_STL(Container)) { return std::remove_if(container.begin(), container.end(), pred); } // remove_copy template <class Type, int Size, class OutputIterator, class Target> inline OutputIterator remove_copy(Type (&ar)[Size], OutputIterator result, const Target& value, void* = 0) { return std::remove_copy(ar, ar + Size, result, value); } template <class Container, class OutputIterator, class Target> inline OutputIterator remove_copy(const Container& container, OutputIterator result, const Target& value, IS_STL(Container)) { return std::remove_copy(container.begin(), container.end(), result, value); } // remove_copy_if template <class Type, int Size, class OutputIterator, class Predicate> inline OutputIterator remove_copy_if(Type (&ar)[Size], OutputIterator result, Predicate pred, void* = 0) { return std::remove_copy_if(ar, ar + Size, result, pred); } template <class Container, class OutputIterator, class Predicate> inline OutputIterator remove_copy_if(const Container& container, OutputIterator result, Predicate pred, IS_STL(Container)) { return std::remove_copy_if(container.begin(), container.end(), result, pred); } // unique template <class Type, int Size> inline Type* unique(Type (&ar)[Size], void* = 0) { return std::unique(ar, ar + Size); } template <class Type, int Size, class BynaryPredicate> inline Type* unique(Type (&ar)[Size], BynaryPredicate pred, void* = 0) { return std::unique(ar, ar + Size, pred); } template <class Container> inline typename Container::iterator unique(Container& container, IS_STL(Container)) { return std::unique(container.begin(), container.end()); } template <class Container, class BynaryPredicate> inline typename Container::iterator unique(Container& container, BynaryPredicate pred, IS_STL(Container)) { return std::unique(container.begin(), container.end(), pred); } // unique_copy template <class Type, int Size, class OutputIterator> inline OutputIterator unique_copy(Type (&ar)[Size], OutputIterator result, void* = 0) { return std::unique_copy(ar, ar + Size, result); } template <class Type, int Size, class OutputIterator, class BynaryPredicate> inline OutputIterator unique_copy(Type (&ar)[Size], OutputIterator result, BynaryPredicate pred, void* = 0) { return std::unique_copy(ar, ar + Size, result, pred); } template <class Container, class OutputIterator> inline OutputIterator unique_copy(const Container& container, OutputIterator result, IS_STL(Container)) { return std::unique_copy(container.begin(), container.end(), result); } template <class Container, class OutputIterator, class BynaryPredicate> inline OutputIterator unique_copy(const Container& container, OutputIterator result, BynaryPredicate pred, IS_STL(Container)) { return std::unique_copy(container.begin(), container.end(), result, pred); } // reverse template <class Type, int Size> inline void reverse(Type (&ar)[Size], void* = 0) { std::reverse(ar, ar + Size); } template <class Container> inline void reverse(Container& container, IS_STL(Container)) { std::reverse(container.begin(), container.end()); } // reverse_copy template <class Type, int Size, class OutputIterator> inline OutputIterator reverse_copy(Type (&ar)[Size], OutputIterator result, void* = 0) { return std::reverse_copy(ar, ar + Size, result); } template <class Container, class OutputIterator> inline OutputIterator reverse_copy(Container& container, OutputIterator result, IS_STL(Container)) { return std::reverse_copy(container.begin(), container.end(), result); } // random_shuffle template <class Type, int Size> inline void random_shuffle(Type (&ar)[Size], void* = 0) { std::random_shuffle(ar, ar + Size); } template <class Type, int Size, class RandomNumberGenerator> inline void random_shuffle(Type (&ar)[Size], RandomNumberGenerator& gen, void* = 0) { std::random_shuffle(ar, ar + Size, gen); } template <class Container> inline void random_shuffle(Container &container, IS_STL(Container)) { std::random_shuffle(container.begin(), container.end()); } template <class Container, class RandomNumberGenerator> inline void random_shuffle(Container &container, RandomNumberGenerator& gen, IS_STL(Container)) { std::random_shuffle(container.begin(), container.end(), gen); } // partition template <class Type, int Size, class Predicate> inline Type* partition(Type (&ar)[Size], Predicate pred, void* = 0) { return std::partition(ar, ar + Size, pred); } template <class Container, class Predicate> inline typename Container::iterator partition(Container& container, Predicate pred, IS_STL(Container)) { return std::partition(container.begin(), container.end(), pred); } // stable_partition template <class Type, int Size, class Predicate> inline Type* stable_partition(Type (&ar)[Size], Predicate pred, void* = 0) { return std::stable_partition(ar, ar + Size, pred); } template <class Container, class Predicate> inline typename Container::iterator stable_partition(Container& container, Predicate pred, IS_STL(Container)) { return std::stable_partition(container.begin(), container.end(), pred); } // sort template <class Type, int Size> inline void sort(Type (&ar)[Size], void* = 0) { std::sort(ar, ar + Size); } template <class Type, int Size, class Compare> inline void sort(Type (&ar)[Size], Compare comp, void* = 0) { std::sort(ar, ar + Size, comp); } template <class Container> inline void sort(Container &container, IS_STL(Container)) { std::sort(container.begin(), container.end()); } template <class Container, class Compare> inline void sort(Container &container, Compare comp, IS_STL(Container)) { std::sort(container.begin(), container.end(), comp); } // stable_sort template <class Type, int Size> inline void stable_sort(Type (&ar)[Size], void* = 0) { std::stable_sort(ar, ar + Size); } template <class Type, int Size, class Compare> inline void stable_sort(Type (&ar)[Size], Compare comp, void* = 0) { std::stable_sort(ar, ar + Size, comp); } template <class Container> inline void stable_sort(Container &container, IS_STL(Container)) { std::stable_sort(container.begin(), container.end()); } template <class Container, class Compare> inline void stable_sort(Container &container, Compare comp, IS_STL(Container)) { std::stable_sort(container.begin(), container.end(), comp); } // lower_bound template <class Type, int Size, class Target> inline Type* lower_bound(Type (&ar)[Size], const Target& value, void* = 0) { return std::lower_bound(ar, ar + Size, value); } template <class Type, int Size, class Target, class Compare> inline Type* lower_bound(Type (&ar)[Size], const Target& value, Compare comp, void* = 0) { return std::lower_bound(ar, ar + Size, value, comp); } template <class Container, class Target> inline typename Container::iterator lower_bound(Container& container, const Target& value, IS_STL(Container)) { return std::lower_bound(container.begin(), container.end(), value); } template <class Container, class Target, class Compare> inline typename Container::iterator lower_bound(Container& container, const Target& value, Compare comp, IS_STL(Container)) { return std::lower_bound(container.begin(), container.end(), value, comp); } template <class Container, class Target> inline typename Container::const_iterator lower_bound(const Container& container, const Target& value, IS_STL(Container)) { return std::lower_bound(container.begin(), container.end(), value); } template <class Container, class Target, class Compare> inline typename Container::const_iterator lower_bound(const Container& container, const Target& value, Compare comp, IS_STL(Container)) { return std::lower_bound(container.begin(), container.end(), value, comp); } // upper_bound template <class Type, int Size, class Target> inline Type* upper_bound(Type (&ar)[Size], const Target& value, void* = 0) { return std::upper_bound(ar, ar + Size, value); } template <class Type, int Size, class Target, class Compare> inline Type* upper_bound(Type (&ar)[Size], const Target& value, Compare comp, void* = 0) { return std::upper_bound(ar, ar + Size, value, comp); } template <class Container, class Target> inline typename Container::iterator upper_bound(Container& container, const Target& value, IS_STL(Container)) { return std::upper_bound(container.begin(), container.end(), value); } template <class Container, class Target, class Compare> inline typename Container::iterator upper_bound(Container& container, const Target& value, Compare comp, IS_STL(Container)) { return std::upper_bound(container.begin(), container.end(), value, comp); } template <class Container, class Target> inline typename Container::const_iterator upper_bound(const Container& container, const Target& value, IS_STL(Container)) { return std::upper_bound(container.begin(), container.end(), value); } template <class Container, class Target, class Compare> inline typename Container::const_iterator upper_bound(const Container& container, const Target& value, Compare comp, IS_STL(Container)) { return std::upper_bound(container.begin(), container.end(), value, comp); } // binary_search template <class Type, int Size, class Target> inline bool binary_search(Type (&ar)[Size], const Target& value, void* = 0) { return std::binary_search(ar, ar + Size, value); } template <class Type, int Size, class Target, class Compare> inline bool binary_search(Type (&ar)[Size], const Target& value, Compare comp, void* = 0) { return std::binary_search(ar, ar + Size, value, comp); } template <class Container, class Target> inline bool binary_search(const Container& container, const Target& value, IS_STL(Container)) { return std::binary_search(container.begin(), container.end(), value); } template <class Container, class Target, class Compare> inline bool binary_search(const Container& container, const Target& value, Compare comp, IS_STL(Container)) { return std::binary_search(container.begin(), container.end(), value, comp); } // merge template <class LType, int LSize, class RType, int RSize, class OutputIterator> inline OutputIterator merge(LType (&lhs)[LSize], RType (&rhs)[RSize], OutputIterator result, void* = 0) { return std::merge(lhs, lhs + LSize, rhs, rhs + RSize, result); } template <class LType, int LSize, class RType, int RSize, class OutputIterator, class Compare> inline OutputIterator merge(LType (&lhs)[LSize], RType (&rhs)[RSize], OutputIterator result, Compare comp, void* = 0) { return std::merge(lhs, lhs + LSize, rhs, rhs + RSize, result, comp); } template <class LContainer, class RContainer, class OutputIterator> inline OutputIterator merge(const LContainer& lhs, const RContainer& rhs, OutputIterator result, IS_STL(LContainer)) { return std::merge(lhs.begin(), lhs.end(), rhs.begin(), rhs.end(), result); } template <class LContainer, class RContainer, class OutputIterator, class Compare> inline OutputIterator merge(const LContainer& lhs, const RContainer& rhs, OutputIterator result, Compare comp, IS_STL(LContainer)) { return std::merge(lhs.begin(), lhs.end(), rhs.begin(), rhs.end(), result, comp); } // includes template <class LType, int LSize, class RType, int RSize> inline bool includes(LType (&lhs)[LSize], RType (&rhs)[RSize], void* = 0) { return std::includes(lhs, lhs + LSize, rhs, rhs + RSize); } template <class LType, int LSize, class RType, int RSize, class Compare> inline bool includes(LType (&lhs)[LSize], RType (&rhs)[RSize], Compare comp, void* = 0) { return std::includes(lhs, lhs + LSize, rhs, rhs + RSize, comp); } template <class LContainer, class RContainer> inline bool includes(const LContainer& lhs, const RContainer& rhs, IS_STL(LContainer)) { return std::includes(lhs.begin(), lhs.end(), rhs.begin(), rhs.end()); } template <class LContainer, class RContainer, class Compare> inline bool includes(const LContainer& lhs, const RContainer& rhs, Compare comp, IS_STL(LContainer)) { return std::includes(lhs.begin(), lhs.end(), rhs.begin(), rhs.end(), comp); } // set_union template <class LType, int LSize, class RType, int RSize, class OutputIterator> inline OutputIterator set_union(LType (&lhs)[LSize], RType (&rhs)[RSize], OutputIterator result, void* = 0) { return std::set_union(lhs, lhs + LSize, rhs, rhs + RSize, result); } template <class LType, int LSize, class RType, int RSize, class OutputIterator, class Compare> inline OutputIterator set_union(LType (&lhs)[LSize], RType (&rhs)[RSize], OutputIterator result, Compare comp, void* = 0) { return std::set_union(lhs, lhs + LSize, rhs, rhs + RSize, result, comp); } template <class LContainer, class RContainer, class OutputIterator> inline OutputIterator set_union(const LContainer& lhs, const RContainer& rhs, OutputIterator result, IS_STL(LContainer)) { return std::set_union(lhs.begin(), lhs.end(), rhs.begin(), rhs.end(), result); } template <class LContainer, class RContainer, class OutputIterator, class Compare> inline OutputIterator set_union(const LContainer& lhs, const RContainer& rhs, OutputIterator result, Compare comp, IS_STL(LContainer)) { return std::set_union(lhs.begin(), lhs.end(), rhs.begin(), rhs.end(), result, comp); } // set_intersection template <class LType, int LSize, class RType, int RSize, class OutputIterator> inline OutputIterator set_intersection(LType (&lhs)[LSize], RType (&rhs)[RSize], OutputIterator result, void* = 0) { return std::set_intersection(lhs, lhs + LSize, rhs, rhs + RSize, result); } template <class LType, int LSize, class RType, int RSize, class OutputIterator, class Compare> inline OutputIterator set_intersection(LType (&lhs)[LSize], RType (&rhs)[RSize], OutputIterator result, Compare comp, void* = 0) { return std::set_intersection(lhs, lhs + LSize, rhs, rhs + RSize, result, comp); } template <class LContainer, class RContainer, class OutputIterator> inline OutputIterator set_intersection(const LContainer& lhs, const RContainer& rhs, OutputIterator result, IS_STL(LContainer)) { return std::set_intersection(lhs.begin(), lhs.end(), rhs.begin(), rhs.end(), result); } template <class LContainer, class RContainer, class OutputIterator, class Compare> inline OutputIterator set_intersection(const LContainer& lhs, const RContainer& rhs, OutputIterator result, Compare comp, IS_STL(LContainer)) { return std::set_intersection(lhs.begin(), lhs.end(), rhs.begin(), rhs.end(), result, comp); } // set_difference template <class LType, int LSize, class RType, int RSize, class OutputIterator> inline OutputIterator set_difference(LType (&lhs)[LSize], RType (&rhs)[RSize], OutputIterator result, void* = 0) { return std::set_difference(lhs, lhs + LSize, rhs, rhs + RSize, result); } template <class LType, int LSize, class RType, int RSize, class OutputIterator, class Compare> inline OutputIterator set_difference(LType (&lhs)[LSize], RType (&rhs)[RSize], OutputIterator result, Compare comp, void* = 0) { return std::set_difference(lhs, lhs + LSize, rhs, rhs + RSize, result, comp); } template <class LContainer, class RContainer, class OutputIterator> inline OutputIterator set_difference(const LContainer& lhs, const RContainer& rhs, OutputIterator result, IS_STL(LContainer)) { return std::set_difference(lhs.begin(), lhs.end(), rhs.begin(), rhs.end(), result); } template <class LContainer, class RContainer, class OutputIterator, class Compare> inline OutputIterator set_difference(const LContainer& lhs, const RContainer& rhs, OutputIterator result, Compare comp, IS_STL(LContainer)) { return std::set_difference(lhs.begin(), lhs.end(), rhs.begin(), rhs.end(), result, comp); } // set_symmetric_difference template <class LType, int LSize, class RType, int RSize, class OutputIterator> inline OutputIterator set_symmetric_difference(LType (&lhs)[LSize], RType (&rhs)[RSize], OutputIterator result, void* = 0) { return std::set_symmetric_difference(lhs, lhs + LSize, rhs, rhs + RSize, result); } template <class LType, int LSize, class RType, int RSize, class OutputIterator, class Compare> inline OutputIterator set_symmetric_difference(LType (&lhs)[LSize], RType (&rhs)[RSize], OutputIterator result, Compare comp, void* = 0) { return std::set_symmetric_difference(lhs, lhs + LSize, rhs, rhs + RSize, result, comp); } template <class LContainer, class RContainer, class OutputIterator> inline OutputIterator set_symmetric_difference(const LContainer& lhs, const RContainer& rhs, OutputIterator result, IS_STL(LContainer)) { return std::set_symmetric_difference(lhs.begin(), lhs.end(), rhs.begin(), rhs.end(), result); } template <class LContainer, class RContainer, class OutputIterator, class Compare> inline OutputIterator set_symmetric_difference(const LContainer& lhs, const RContainer& rhs, OutputIterator result, Compare comp, IS_STL(LContainer)) { return std::set_symmetric_difference(lhs.begin(), lhs.end(), rhs.begin(), rhs.end(), result, comp); } // push_heap template <class Type, int Size> inline void push_heap(Type (&ar)[Size], void* = 0) { std::push_heap(ar, ar + Size); } template <class Type, int Size, class Compare> inline void push_heap(Type (&ar)[Size], Compare comp, void* = 0) { std::push_heap(ar, ar + Size, comp); } template <class Container> inline void push_heap(Container& container, IS_STL(Container)) { std::push_heap(container.begin(), container.end()); } template <class Container, class Compare> inline void push_heap(Container& container, Compare comp, IS_STL(Container)) { std::push_heap(container.begin(), container.end(), comp); } // pop_heap template <class Type, int Size> inline void pop_heap(Type (&ar)[Size], void* = 0) { std::pop_heap(ar, ar + Size); } template <class Type, int Size, class Compare> inline void pop_heap(Type (&ar)[Size], Compare comp, void* = 0) { std::pop_heap(ar, ar + Size, comp); } template <class Container> inline void pop_heap(Container& container, IS_STL(Container)) { std::pop_heap(container.begin(), container.end()); } template <class Container, class Compare> inline void pop_heap(Container& container, Compare comp, IS_STL(Container)) { std::pop_heap(container.begin(), container.end(), comp); } // make_heap template <class Type, int Size> inline void make_heap(Type (&ar)[Size], void* = 0) { std::make_heap(ar, ar + Size); } template <class Type, int Size, class Compare> inline void make_heap(Type (&ar)[Size], Compare comp, void* = 0) { std::make_heap(ar, ar + Size, comp); } template <class Container> inline void make_heap(Container& container, IS_STL(Container)) { std::make_heap(container.begin(), container.end()); } template <class Container, class Compare> inline void make_heap(Container& container, Compare comp, IS_STL(Container)) { std::make_heap(container.begin(), container.end(), comp); } // sort_heap template <class Type, int Size> inline void sort_heap(Type (&ar)[Size], void* = 0) { std::sort_heap(ar, ar + Size); } template <class Type, int Size, class Compare> inline void sort_heap(Type (&ar)[Size], Compare comp, void* = 0) { std::sort_heap(ar, ar + Size, comp); } template <class Container> inline void sort_heap(Container& container, IS_STL(Container)) { std::sort_heap(container.begin(), container.end()); } template <class Container, class Compare> inline void sort_heap(Container& container, Compare comp, IS_STL(Container)) { std::sort_heap(container.begin(), container.end(), comp); } // min_element template <class Type, int Size> inline Type* min_element(Type (&ar)[Size], void* = 0) { return std::min_element(ar, ar + Size); } template <class Type, int Size, class Compare> inline Type* min_element(Type (&ar)[Size], Compare comp, void* = 0) { return std::min_element(ar, ar + Size, comp); } template <class Container> inline typename Container::iterator min_element(Container& container, IS_STL(Container)) { return std::min_element(container.begin(), container.end()); } template <class Container, class Compare> inline typename Container::iterator min_element(Container& container, Compare comp, IS_STL(Container)) { return std::min_element(container.begin(), container.end(), comp); } template <class Container> inline typename Container::const_iterator min_element(const Container& container, IS_STL(Container)) { return std::min_element(container.begin(), container.end()); } template <class Container, class Compare> inline typename Container::const_iterator min_element(const Container& container, Compare comp, IS_STL(Container)) { return std::min_element(container.begin(), container.end(), comp); } // max_element template <class Type, int Size> inline Type* max_element(Type (&ar)[Size], void* = 0) { return std::max_element(ar, ar + Size); } template <class Type, int Size, class Compare> inline Type* max_element(Type (&ar)[Size], Compare comp, void* = 0) { return std::max_element(ar, ar + Size, comp); } template <class Container> inline typename Container::iterator max_element(Container& container, IS_STL(Container)) { return std::max_element(container.begin(), container.end()); } template <class Container, class Compare> inline typename Container::iterator max_element(Container& container, Compare comp, IS_STL(Container)) { return std::max_element(container.begin(), container.end(), comp); } template <class Container> inline typename Container::const_iterator max_element(const Container& container, IS_STL(Container)) { return std::max_element(container.begin(), container.end()); } template <class Container, class Compare> inline typename Container::const_iterator max_element(const Container& container, Compare comp, IS_STL(Container)) { return std::max_element(container.begin(), container.end(), comp); } // lexicographical_compare template <class LType, int LSize, class RType, int RSize> inline bool lexicographical_compare(LType (&lhs)[LSize], RType (&rhs)[RSize], void* = 0) { return std::lexicographical_compare(lhs, lhs + LSize, rhs, rhs + RSize); } template <class LType, int LSize, class RType, int RSize, class Compare> inline bool lexicographical_compare(LType (&lhs)[LSize], RType (&rhs)[RSize], Compare comp, void* = 0) { return std::lexicographical_compare(lhs, lhs + LSize, rhs, rhs + RSize, comp); } template <class LContainer, class RContainer> inline bool lexicographical_compare(const LContainer& lhs, const RContainer& rhs, IS_STL(LContainer)) { return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end()); } template <class LContainer, class RContainer, class Compare> inline bool lexicographical_compare(const LContainer& lhs, const RContainer& rhs, Compare comp, IS_STL(LContainer)) { return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end(), comp); } // next_permutation template <class Type, int Size> inline bool next_permutation(Type (&ar)[Size], void* = 0) { return std::next_permutation(ar, ar + Size); } template <class Type, int Size, class Compare> inline bool next_permutation(Type (&ar)[Size], Compare comp, void* = 0) { return std::next_permutation(ar, ar + Size, comp); } template <class Container> inline bool next_permutation(Container& container, IS_STL(Container)) { return std::next_permutation(container.begin(), container.end()); } template <class Container, class Compare> inline bool next_permutation(Container& container, Compare comp, IS_STL(Container)) { return std::next_permutation(container.begin(), container.end(), comp); } // prev_permutation template <class Type, int Size> inline bool prev_permutation(Type (&ar)[Size], void* = 0) { return std::prev_permutation(ar, ar + Size); } template <class Type, int Size, class Compare> inline bool prev_permutation(Type (&ar)[Size], Compare comp, void* = 0) { return std::prev_permutation(ar, ar + Size, comp); } template <class Container> inline bool prev_permutation(Container& container, IS_STL(Container)) { return std::prev_permutation(container.begin(), container.end()); } template <class Container, class Compare> inline bool prev_permutation(Container& container, Compare comp, IS_STL(Container)) { return std::prev_permutation(container.begin(), container.end(), comp); } #endif // SHAND_SUPPORT_SFINAE } // namespace shand #undef SHAND_SUPPORT_SFINAE #undef IS_STL