2019-01-11-01-not_fnの追加 - project-enigma

2019-01-11-01-not_fnの追加

>> Site top >> weblog >> 月別アーカイブ >> 2019年01月のlog >> 2019-01-11-01-not_fnの追加

最終更新日付:2019/01/11 20:41:03


not_fnの追加

2019 年 01 月 11 日

C++17 で、not_fn というのが追加された。可変長テンプレートを利用して以下を置き換えるものだ。

今回はその not_fn を追加する対応。

STL の実装を見る限り、結局は指定された関数にパラメータを転送して、結果に ! 演算子を適用するだけのモノのようだ。CL-STL のことを忘れ過ぎている自分は、最初勘違いして以下でいいと思ってしまった。

#-(or cl-stl-0x98 cl-stl-0x11 cl-stl-0x14)
(locally (declare (optimize speed))
  (defun not_fn (fnc)
    (lambda (&rest params)
      (_! (apply fnc params)))))

 

しかし、上記は全然間違っていた。原則として、CL-STL のファンクタは functor 派生の funcallable なクラスにするのだった。というわけでやりなおしたのが以下。

#-(or cl-stl-0x98 cl-stl-0x11 cl-stl-0x14)
(define-functor __not_fn (functor)
  ((op  :initform nil
        :initarg  :operator
        :accessor __not_fn-operator)))

#-(or cl-stl-0x98 cl-stl-0x11 cl-stl-0x14)
(defun not_fn (functor)
  (let* ((op  (clone functor))
         (fnc (functor_function op)))
    (make-instance '__not_fn
                   :operator op
                   :closure (lambda (&rest params)
                              (_! (cl:apply fnc params))))))

#-(or cl-stl-0x98 cl-stl-0x11 cl-stl-0x14)
(defmethod operator_clone ((func __not_fn))
  (let* ((op   (clone (__not_fn-operator func)))
         (fnc  (functor_function op)))
    (make-instance '__not_fn
                   :operator op
                   :closure (lambda (&rest params)
                              (_! (cl:apply fnc params))))))

 

まぁ、そういった事情があるので、単純にクロージャを返すことができない。そして、C++ の文脈で言えば operator! がオーバーロードされている場合の挙動を模倣する必要があるので、cl-overload の _! を使用する必要がある。そういったアレコレのせいで、「いったい誰が使うんだ?」というモノになってしまった。まぁ、CL-STL のファンクタはほぼ全部がそうだよな‥‥‥。

 

コメント

このページにコメントする

 

このページのタグ

Page tag : STLとその移植

Page tag : Common Lisp

 

 


Copyright(C) 2005-2019 project-enigma.
Generated by CL-PREFAB.