Changeset 22ba300 in mainline


Ignore:
Timestamp:
2018-07-05T21:41:19Z (6 years ago)
Author:
Dzejrou <dzejrou@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
ee51635
Parents:
e65c9285
git-author:
Dzejrou <dzejrou@…> (2018-03-01 17:42:10)
git-committer:
Dzejrou <dzejrou@…> (2018-07-05 21:41:19)
Message:

fixed compile errors, added a generic hash function, fixed static asserts

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/cpp/include/impl/functional.hpp

    re65c9285 r22ba300  
    3030#define LIBCPP_FUNCTIONAL
    3131
     32#include <limits>
    3233#include <type_traits>
    33 
    34 extern "C" {
    35 #include <adt/hash.h>
    36 }
     34#include <utility>
    3735
    3836namespace std
     
    4442         */
    4543        template<class R, class T, class T1, class... Ts>
    46         decltype(auto) invoke(R T::* f, T1&& t1, Args&&... args)
     44        decltype(auto) invoke(R T::* f, T1&& t1, Ts&&... args)
    4745        {
    4846            if constexpr (is_member_function_pointer_v<decltype(f)>)
     
    5048                if constexpr (is_base_of_v<T, remove_reference_t<T1>>)
    5149                    // (1.1)
    52                     return (t1.*f)(forward<Args>(args)...);
     50                    return (t1.*f)(forward<Ts>(args)...);
    5351                else
    5452                    // (1.2)
    55                     return ((*t1).*f)(forward<Args>(args)...);
     53                    return ((*t1).*f)(forward<Ts>(args)...);
    5654            }
    57             else if (is_member_object_pointer_v<decltype(f)> && sizeof...(args) == 0)
     55            else if constexpr (is_member_object_pointer_v<decltype(f)> && sizeof...(args) == 0)
    5856            {
    5957                /**
     
    6866                    return (*t1).*f;
    6967            }
    70             static_assert(false, "invalid invoke");
     68
     69            /**
     70             * Note: If this condition holds this will not be reachable,
     71             *       but a new addition to the standard (17.7 point (8.1))
     72             *       prohibits us from simply using false as the condition here,
     73             *       so we use this because we know it is false here.
     74             */
     75            static_assert(is_member_function_pointer_v<decltype(f)>, "invalid invoke");
    7176        }
    7277
     
    208213    {
    209214        template<class T, class U>
    210         constexpr auto operator(T&& lhs, U&& rhs) const
     215        constexpr auto operator()(T&& lhs, U&& rhs) const
    211216            -> decltype(forward<T>(lhs) + forward<U>(rhs))
    212217        {
     
    221226    {
    222227        template<class T, class U>
    223         constexpr auto operator(T&& lhs, U&& rhs) const
     228        constexpr auto operator()(T&& lhs, U&& rhs) const
    224229            -> decltype(forward<T>(lhs) - forward<U>(rhs))
    225230        {
     
    234239    {
    235240        template<class T, class U>
    236         constexpr auto operator(T&& lhs, U&& rhs) const
     241        constexpr auto operator()(T&& lhs, U&& rhs) const
    237242            -> decltype(forward<T>(lhs) * forward<U>(rhs))
    238243        {
     
    247252    {
    248253        template<class T, class U>
    249         constexpr auto operator(T&& lhs, U&& rhs) const
     254        constexpr auto operator()(T&& lhs, U&& rhs) const
    250255            -> decltype(forward<T>(lhs) / forward<U>(rhs))
    251256        {
     
    260265    {
    261266        template<class T, class U>
    262         constexpr auto operator(T&& lhs, U&& rhs) const
     267        constexpr auto operator()(T&& lhs, U&& rhs) const
    263268            -> decltype(forward<T>(lhs) % forward<U>(rhs))
    264269        {
     
    273278    {
    274279        template<class T>
    275         constexpr auto operator(T&& x) const
     280        constexpr auto operator()(T&& x) const
    276281            -> decltype(-forward<T>(x))
    277282        {
     
    287292
    288293    template<class T = void>
    289     struct equal_to;
     294    struct equal_to
    290295    {
    291296        constexpr bool operator()(const T& lhs, const T& rhs) const
     
    368373    {
    369374        template<class T, class U>
    370         constexpr auto operator(T&& lhs, U&& rhs) const
     375        constexpr auto operator()(T&& lhs, U&& rhs) const
    371376            -> decltype(forward<T>(lhs) == forward<U>(rhs))
    372377        {
     
    381386    {
    382387        template<class T, class U>
    383         constexpr auto operator(T&& lhs, U&& rhs) const
     388        constexpr auto operator()(T&& lhs, U&& rhs) const
    384389            -> decltype(forward<T>(lhs) != forward<U>(rhs))
    385390        {
     
    394399    {
    395400        template<class T, class U>
    396         constexpr auto operator(T&& lhs, U&& rhs) const
     401        constexpr auto operator()(T&& lhs, U&& rhs) const
    397402            -> decltype(forward<T>(lhs) > forward<U>(rhs))
    398403        {
     
    407412    {
    408413        template<class T, class U>
    409         constexpr auto operator(T&& lhs, U&& rhs) const
     414        constexpr auto operator()(T&& lhs, U&& rhs) const
    410415            -> decltype(forward<T>(lhs) < forward<U>(rhs))
    411416        {
     
    420425    {
    421426        template<class T, class U>
    422         constexpr auto operator(T&& lhs, U&& rhs) const
     427        constexpr auto operator()(T&& lhs, U&& rhs) const
    423428            -> decltype(forward<T>(lhs) >= forward<U>(rhs))
    424429        {
     
    433438    {
    434439        template<class T, class U>
    435         constexpr auto operator(T&& lhs, U&& rhs) const
     440        constexpr auto operator()(T&& lhs, U&& rhs) const
    436441            -> decltype(forward<T>(lhs) <= forward<U>(rhs))
    437442        {
     
    488493    {
    489494        template<class T, class U>
    490         constexpr auto operator(T&& lhs, U&& rhs) const
     495        constexpr auto operator()(T&& lhs, U&& rhs) const
    491496            -> decltype(forward<T>(lhs) && forward<U>(rhs))
    492497        {
     
    501506    {
    502507        template<class T, class U>
    503         constexpr auto operator(T&& lhs, U&& rhs) const
     508        constexpr auto operator()(T&& lhs, U&& rhs) const
    504509            -> decltype(forward<T>(lhs) || forward<U>(rhs))
    505510        {
     
    514519    {
    515520        template<class T>
    516         constexpr auto operator(T&& x) const
     521        constexpr auto operator()(T&& x) const
    517522            -> decltype(!forward<T>(x))
    518523        {
    519             return !forward<T>(lhs);
     524            return !forward<T>(x);
    520525        }
    521526
     
    582587    {
    583588        template<class T, class U>
    584         constexpr auto operator(T&& lhs, U&& rhs) const
     589        constexpr auto operator()(T&& lhs, U&& rhs) const
    585590            -> decltype(forward<T>(lhs) & forward<U>(rhs))
    586591        {
     
    595600    {
    596601        template<class T, class U>
    597         constexpr auto operator(T&& lhs, U&& rhs) const
     602        constexpr auto operator()(T&& lhs, U&& rhs) const
    598603            -> decltype(forward<T>(lhs) | forward<U>(rhs))
    599604        {
     
    608613    {
    609614        template<class T, class U>
    610         constexpr auto operator(T&& lhs, U&& rhs) const
     615        constexpr auto operator()(T&& lhs, U&& rhs) const
    611616            -> decltype(forward<T>(lhs) ^ forward<U>(rhs))
    612617        {
     
    621626    {
    622627        template<class T>
    623         constexpr auto operator(T&& x) const
     628        constexpr auto operator()(T&& x) const
    624629            -> decltype(~forward<T>(x))
    625630        {
    626             return ~forward<T>(lhs);
     631            return ~forward<T>(x);
    627632        }
    628633
     
    710715     */
    711716
     717    namespace aux
     718    {
     719        template<class T>
     720        union converter
     721        {
     722            T value;
     723            uint64_t converted;
     724        };
     725
     726        template<class T>
     727        T hash_(uint64_t x) noexcept
     728        {
     729            // TODO: This is copied form adt/hash (temporarily),
     730            //       check if we can use something better.
     731            x = (x ^ 61) ^ (x >> 16);
     732            x = x + (x << 3);
     733            x = x ^ (x >> 4);
     734            x = x * 0x27d4eb2d;
     735            x = x ^ (x >> 15);
     736
     737            return static_cast<T>((x << 32) | (x >> 32));
     738        }
     739
     740        template<class T>
     741        size_t hash(T x) noexcept
     742        {
     743            static_assert(is_arithmetic_v<T> || is_pointer_v<T>,
     744                          "invalid type passed to aux::hash");
     745
     746            converter<T> conv;
     747            conv.value = x;
     748
     749            return hash_<size_t>(conv.converted);
     750        }
     751    }
     752
    712753    template<class T>
    713754    struct hash
     
    719760        size_t operator()(bool x) const noexcept
    720761        {
    721             return hash_mix(static_cast<size_t>(x));
     762            return aux::hash(x);
    722763        }
    723764
     
    731772        size_t operator()(char x) const noexcept
    732773        {
    733             return hash_mix(static_cast<size_t>(x));
     774            return aux::hash(x);
    734775        }
    735776
     
    743784        size_t operator()(signed char x) const noexcept
    744785        {
    745             return hash_mix(static_cast<size_t>(x));
     786            return aux::hash(x);
    746787        }
    747788
     
    755796        size_t operator()(unsigned char x) const noexcept
    756797        {
    757             return hash_mix(static_cast<size_t>(x));
     798            return aux::hash(x);
    758799        }
    759800
     
    767808        size_t operator()(char16_t x) const noexcept
    768809        {
    769             return hash_mix(static_cast<size_t>(x));
     810            return aux::hash(x);
    770811        }
    771812
     
    779820        size_t operator()(char32_t x) const noexcept
    780821        {
    781             return hash_mix(static_cast<size_t>(x));
     822            return aux::hash(x);
    782823        }
    783824
     
    791832        size_t operator()(wchar_t x) const noexcept
    792833        {
    793             return hash_mix(static_cast<size_t>(x));
     834            return aux::hash(x);
    794835        }
    795836
     
    803844        size_t operator()(short x) const noexcept
    804845        {
    805             return hash_mix(static_cast<size_t>(x));
     846            return aux::hash(x);
    806847        }
    807848
     
    815856        size_t operator()(unsigned short x) const noexcept
    816857        {
    817             return hash_mix(static_cast<size_t>(x));
     858            return aux::hash(x);
    818859        }
    819860
     
    827868        size_t operator()(int x) const noexcept
    828869        {
    829             return hash_mix(static_cast<size_t>(x));
     870            return aux::hash(x);
    830871        }
    831872
     
    839880        size_t operator()(unsigned int x) const noexcept
    840881        {
    841             return hash_mix(static_cast<size_t>(x));
     882            return aux::hash(x);
    842883        }
    843884
     
    851892        size_t operator()(long x) const noexcept
    852893        {
    853             return hash_mix(static_cast<size_t>(x));
     894            return aux::hash(x);
    854895        }
    855896
     
    863904        size_t operator()(long long x) const noexcept
    864905        {
    865             return hash_mix(static_cast<size_t>(x));
     906            return aux::hash(x);
    866907        }
    867908
     
    875916        size_t operator()(unsigned long x) const noexcept
    876917        {
    877             return hash_mix(static_cast<size_t>(x));
     918            return aux::hash(x);
    878919        }
    879920
     
    887928        size_t operator()(unsigned long long x) const noexcept
    888929        {
    889             return hash_mix(static_cast<size_t>(x));
     930            return aux::hash(x);
    890931        }
    891932
     
    899940        size_t operator()(float x) const noexcept
    900941        {
    901             return hash_mix(*(size_t*)(&x));
     942            return aux::hash(x);
    902943        }
    903944
     
    907948
    908949    template<>
    909     struct hash<double>;
     950    struct hash<double>
    910951    {
    911952        size_t operator()(double x) const noexcept
    912953        {
    913             return hash_mix(*(size_t*)(&x));
     954            return aux::hash(x);
    914955        }
    915956
     
    919960
    920961    template<>
    921     struct hash<long double>;
     962    struct hash<long double>
    922963    {
    923964        size_t operator()(long double x) const noexcept
    924965        {
    925             return hash_mix(*(size_t*)(&x));
     966            return aux::hash(x);
    926967        }
    927968
     
    935976        size_t operator()(T* x) const noexcept
    936977        {
    937             return hash_mix(static_cast<size_t>(x));
     978            return aux::hash(x);
    938979        }
    939980
Note: See TracChangeset for help on using the changeset viewer.