Ignore:
Timestamp:
2018-07-05T21:41:22Z (6 years ago)
Author:
Dzejrou <dzejrou@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
800968b7
Parents:
2c223a9d
git-author:
Dzejrou <dzejrou@…> (2018-05-04 00:50:37)
git-committer:
Dzejrou <dzejrou@…> (2018-07-05 21:41:22)
Message:

cpp: added working bind, but it does not handle references yet

File:
1 edited

Legend:

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

    r2c223a9d ra30c04d  
    758758
    759759    /**
    760      * 20.9.10, bind:
    761      */
    762 
    763     template<class T>
    764     struct is_bind_expression;
    765 
    766     template<class T>
    767     struct is_placeholder;
    768 
    769     // TODO: void should be /unspecified/
    770     template<class F, class... Args>
    771     void bind(F&& f, Args&&... args);
    772 
    773     template<class R, class F, class... Args>
    774     void bind(F&& f, Args&&... args);
    775 
    776     namespace placeholders
    777     {
    778         /**
    779          * TODO: for X from 1 to implementation defined M
    780          * extern /unspecified/ _X;
    781          */
    782     }
    783 
    784     /**
    785      * 20.9.11, member function adaptors:
    786      */
    787 
    788     namespace aux
    789     {
    790         template<class F>
    791         class mem_fn_t
    792         {
    793             // TODO: conditional typedefs
    794             public:
    795                 mem_fn_t(F f)
    796                     : func_{f}
    797                 { /* DUMMY BODY */ }
    798 
    799                 template<class... Args>
    800                 decltype(auto) operator()(Args&&... args)
    801                 {
    802                     return invoke(func_, forward<Args>(args)...);
    803                 }
    804 
    805             private:
    806                 F func_;
    807         };
    808     }
    809 
    810     template<class R, class T>
    811     aux::mem_fn_t<R T::*> mem_fn(R T::* f)
    812     {
    813         return aux::mem_fn_t<R T::*>{f};
    814     }
    815 
    816     /**
    817760     * 20.9.12, polymorphic function adaptors:
    818761     */
     
    856799    }
    857800
     801    // TODO: implement
    858802    class bad_function_call;
    859803
     
    11491093        : true_type
    11501094    { /* DUMMY BODY */ };
     1095
     1096    /**
     1097     * 20.9.10, bind:
     1098     */
     1099
     1100    namespace aux
     1101    {
     1102        template<int N>
     1103        struct placeholder_t
     1104        {
     1105            constexpr placeholder_t() = default;
     1106        };
     1107    }
     1108
     1109    template<class T>
     1110    struct is_placeholder: integral_constant<int, 0>
     1111    { /* DUMMY BODY */ };
     1112
     1113    template<int N> // Note: const because they are all constexpr.
     1114    struct is_placeholder<const aux::placeholder_t<N>>
     1115        : integral_constant<int, N>
     1116    { /* DUMMY BODY */ };
     1117
     1118    template<class T>
     1119    inline constexpr int is_placeholder_v = is_placeholder<T>::value;
     1120
     1121    namespace aux
     1122    {
     1123        template<size_t I>
     1124        struct bind_arg_index
     1125        { /* DUMMY BODY */ };
     1126
     1127        template<class... Args>
     1128        class bind_bound_args
     1129        {
     1130            public:
     1131                template<class... BoundArgs>
     1132                constexpr bind_bound_args(BoundArgs&&... args)
     1133                    : tpl_{forward<BoundArgs>(args)...}
     1134                { /* DUMMY BODY */ }
     1135
     1136                template<size_t I>
     1137                constexpr decltype(auto) operator[](bind_arg_index<I>)
     1138                {
     1139                    return get<I>(tpl_);
     1140                }
     1141
     1142            private:
     1143                tuple<Args...> tpl_;
     1144        };
     1145
     1146        template<class... Args>
     1147        class bind_arg_filter
     1148        {
     1149            public:
     1150                bind_arg_filter(Args&&... args)
     1151                    : args_{forward<Args>(args)...}
     1152                { /* DUMMY BODY */ }
     1153
     1154                // TODO: enable if T != ref_wrapper
     1155                template<class T>
     1156                constexpr decltype(auto) operator[](T&& t)
     1157                { // Since placeholders are constexpr, this is a worse match for them.
     1158                    return forward<T>(t);
     1159                }
     1160
     1161                template<int N>
     1162                constexpr decltype(auto) operator[](const placeholder_t<N>)
     1163                {
     1164                    /**
     1165                     * Come on, it's int! Why not use -1 as not placeholder
     1166                     * and start them at 0? -.-
     1167                     */
     1168                    /* return get<is_placeholder_v<decay_t<T>> - 1>(args_); */
     1169                    return get<N - 1>(args_);
     1170                }
     1171
     1172                // TODO: overload the operator for reference_wrapper
     1173
     1174            private:
     1175                tuple<Args...> args_;
     1176        };
     1177
     1178        template<class F, class... Args>
     1179        class bind_t
     1180        {
     1181            // TODO: conditional typedefs
     1182            public:
     1183                template<class... BoundArgs>
     1184                constexpr bind_t(F&& f, BoundArgs&&... args)
     1185                    : func_{forward<F>(f)},
     1186                      bound_args_{forward<BoundArgs>(args)...}
     1187                { /* DUMMY BODY */ }
     1188
     1189                template<class... ActualArgs>
     1190                constexpr decltype(auto) operator()(ActualArgs&&... args)
     1191                {
     1192                    return invoke_(
     1193                        make_index_sequence<sizeof...(Args)>{},
     1194                        forward<ActualArgs>(args)...
     1195                    );
     1196                }
     1197
     1198            private:
     1199                function<decay_t<F>> func_;
     1200                bind_bound_args<Args...> bound_args_;
     1201
     1202                template<size_t... Is, class... ActualArgs>
     1203                constexpr decltype(auto) invoke_(
     1204                    index_sequence<Is...>, ActualArgs&&... args
     1205                )
     1206                {
     1207                    bind_arg_filter<ActualArgs...> filter{forward<ActualArgs>(args)...};
     1208
     1209                    return invoke(
     1210                        func_,
     1211                        filter[bound_args_[bind_arg_index<Is>()]]...
     1212                    );
     1213                }
     1214        };
     1215    }
     1216
     1217    template<class T>
     1218    struct is_bind_expression: false_type
     1219    { /* DUMMY BODY */ };
     1220
     1221    template<class F, class... Args>
     1222    struct is_bind_expression<aux::bind_t<F, Args...>>
     1223        : true_type
     1224    { /* DUMMY BODY */ };
     1225
     1226    template<class F, class... Args>
     1227    aux::bind_t<F, Args...> bind(F&& f, Args&&... args)
     1228    {
     1229        return aux::bind_t<F, Args...>{forward<F>(f), forward<Args>(args)...};
     1230    }
     1231
     1232    template<class R, class F, class... Args>
     1233    aux::bind_t<F, Args...> bind(F&& f, Args&&... args);
     1234
     1235    namespace placeholders
     1236    {
     1237        /**
     1238         * Note: The number of placeholders is
     1239         *       implementation defined, we've chosen
     1240         *       8 because it is a nice number
     1241         *       and should be enough for any function
     1242         *       call.
     1243         * Note: According to the C++14 standard, these
     1244         *       are all extern non-const. We decided to use
     1245         *       the C++17 form of them being inline constexpr
     1246         *       because it is more convenient, makes sense
     1247         *       and would eventually need to be upgraded
     1248         *       anyway.
     1249         */
     1250        inline constexpr aux::placeholder_t<1> _1;
     1251        inline constexpr aux::placeholder_t<2> _2;
     1252        inline constexpr aux::placeholder_t<3> _3;
     1253        inline constexpr aux::placeholder_t<4> _4;
     1254        inline constexpr aux::placeholder_t<5> _5;
     1255        inline constexpr aux::placeholder_t<6> _6;
     1256        inline constexpr aux::placeholder_t<7> _7;
     1257        inline constexpr aux::placeholder_t<8> _8;
     1258    }
     1259
     1260    /**
     1261     * 20.9.11, member function adaptors:
     1262     */
     1263
     1264    namespace aux
     1265    {
     1266        template<class F>
     1267        class mem_fn_t
     1268        {
     1269            // TODO: conditional typedefs
     1270            public:
     1271                mem_fn_t(F f)
     1272                    : func_{f}
     1273                { /* DUMMY BODY */ }
     1274
     1275                template<class... Args>
     1276                decltype(auto) operator()(Args&&... args)
     1277                {
     1278                    return invoke(func_, forward<Args>(args)...);
     1279                }
     1280
     1281            private:
     1282                F func_;
     1283        };
     1284    }
     1285
     1286    template<class R, class T>
     1287    aux::mem_fn_t<R T::*> mem_fn(R T::* f)
     1288    {
     1289        return aux::mem_fn_t<R T::*>{f};
     1290    }
    11511291
    11521292    /**
Note: See TracChangeset for help on using the changeset viewer.