r203293 - [C++11] Revert uses of lambdas with array_pod_sort.
Arthur O'Dwyer
arthur.j.odwyer at gmail.com
Thu Mar 20 18:45:18 PDT 2014
On Mon, Mar 10, 2014 at 2:46 PM, Richard Smith <richard at metafoo.co.uk> wrote:
> On Mon, Mar 10, 2014 at 12:12 PM, Arthur O'Dwyer <arthur.j.odwyer at gmail.com> wrote:
>> On Sun, Mar 9, 2014 at 9:32 PM, David Blaikie <dblaikie at gmail.com> wrote:
>> > If you're suggesting that tie+op< isn't an idiom we should generally adopt
>> > it'd be nice to build something like it that would be appropriate. (Not sure
>> > if there's something that should be standardized in some form as this idiom
>> > seems like it will be common)
[…]
> More efficient implementation (also untested):
>
> namespace llvm {
> template<typename T> int cmp(const T &a, const T &b) {
> return a < b ? -1 :
> a > b ? 1 : 0;
> // or for an efficient implementation that assumes == and < are compatible:
> // return a == b ? 0 :
> // a < b ? -1 : 1;
> }
> template<typename ...Args> int cmp(const std::tuple<Args...> &a, const
> std::tuple<Args...> &b);
>
> template<typename Tuple, int I, bool Done = I ==
> std::tuple_size<Tuple>::value>
> struct cmp_impl {
> int operator()(const Tuple &a, const Tuple &b) const {
> int result = cmp(std::get<I>(a), std::get<I>(b));
> return result ? result : cmp_impl<Tuple, I + 1>()(a, b);
> }
> };
> template<typename Tuple, int I> struct cmp_impl<Tuple, I, true> {
> int operator()(const Tuple &, const Tuple &) const { return 0; }
> };
> template<typename ...Args>
> int cmp(const std::tuple<Args...> &a, const std::tuple<Args...> &b) {
> return cmp_impl<std::tuple<Args...>, 0>()(a, b);
> }
> }
Here's yet another offering, this one based on libc++'s implementation
of operator< for tuples.
(I write __tuple_spaceship where libc++ has __tuple_less.) I made
some things constexpr because "why not". Notice the overload for
std::string; it would be a good idea to add overloads for
LLVM-specific string types too.
namespace llvm {
template <class _Tp, class _Up>
constexpr int spaceship(const _Tp& __x, const _Up& __y)
{
return (__x < __y) ? -1 : (__y < __x) ? 1 : 0;
}
template <size_t _Ip>
struct __tuple_spaceship
{
template <class _Tp, class _Up>
constexpr int __step2(int __r, const _Tp& __x, const _Up& __y) const
{
// in C++14 this would just be the second line of operator()
return (__r != 0) ? __r : spaceship(std::get<_Ip-1>(__x),
std::get<_Ip-1>(__y)); // ADL
}
template <class _Tp, class _Up>
constexpr int operator()(const _Tp& __x, const _Up& __y) const
{
return __step2(__tuple_spaceship<_Ip-1>()(__x, __y), __x, __y);
}
};
template <>
struct __tuple_spaceship<0>
{
template <class _Tp, class _Up>
constexpr int operator()(const _Tp&, const _Up&) const
{
return 0;
}
};
template <class ..._Tp, class ..._Up>
constexpr int spaceship(const std::tuple<_Tp...>& __x, const
std::tuple<_Up...>& __y)
{
return __tuple_spaceship<sizeof...(_Tp)>()(__x, __y);
}
template<class _Cp, class _Tp, class _Ap,
class _Up, class _Bp>
int spaceship(const std::basic_string<_Cp,_Tp,_Ap>& __x,
const std::basic_string<_Cp,_Up,_Bp>& __y)
{
int __r = __x.compare(0, __x.size(), __y.data(), __y.size());
return (__r < 0) ? -1 : (__r > 0);
}
} // namespace llvm
More information about the cfe-commits
mailing list