キューのメッセージパッシング手続き実装と問題3.22
C++11でキューのデータの実体オブジェクトfrontPointerを、
makeQueue内で定義すると、frontPointerを各クロージャで共有するためには、
クロージャでfrontPointerを参照キャプチャしなければいけないが、
makeQueueが終了すると本体の寿命が尽きて、クロージャ内の参照も全部死ぬ。
そこでmakeQueueではfrontPointerの初期値を設定するのみにし、
frontPointerをスタックに入れて右辺値参照で保持するようにした。ああ面倒。
しかも右辺値参照だとなぜ保持できてるのかわからない。
仕様なのか実装系依存なのか。気持ち悪い。
デックはあまり興味ないので問題3.23はパス。
普通はデキューでなくデックじゃないかと思うがまあいいや。
----
typedef
function<List(List)> Queue;
const
Queue makeQueueDispatch(const List& initial)
{
const List&&
frontPointer(std::move(initial));
const function<bool(void)>
isEmptyQueue
=[frontPointer](void){return(isNull(frontPointer));};
const function<List(void)> frontQueue
=[frontPointer,isEmptyQueue](void){
if(isEmptyQueue()){
cerr<<"FRONT called with an empty queue
"<<listString(frontPointer)<<endl;
exit(1);
return(makeList());
}
return(car(frontPointer));
};
const function<void(List)>
setfFrontPointer
=[frontPointer](const List& item)
{setfCar(frontPointer,item);};
const function<List(List)>
insertfQueue
=[frontPointer,isEmptyQueue,setfFrontPointer]
(const List& item)
{
if(isEmptyQueue()){
setfFrontPointer(item);
}else{
appendf(frontPointer,makeList(item));
}
return(frontPointer);
};
const function<List(void)>
deletefQueue
=[frontPointer,isEmptyQueue](void)
{
if(isEmptyQueue()){
cerr<<"DELETE! called
with an empty queue "<<listString(frontPointer)<<endl;
exit(1);
return(makeList());
}
setf(cdr(frontPointer),frontPointer);
return(frontPointer);
};
const function<List(void)>
getQueue=[frontPointer](void)
{return(frontPointer);};
const Queue dispatch
=[isEmptyQueue,frontQueue,insertfQueue,deletefQueue,getQueue]
(const List& message){
if(isEq(message,makeLeaf("empty-queue?"))){return(makeLeaf(isEmptyQueue));}
if(isEq(message,makeLeaf("front-queue"))){return(makeLeaf(frontQueue));}
if(isEq(message,makeLeaf("insert-queue!"))){return(makeLeaf(insertfQueue));}
if(isEq(message,makeLeaf("delete-queue!"))){return(makeLeaf(deletefQueue));}
if(isEq(message,makeLeaf("get-queue"))){return(makeLeaf(getQueue));}
cerr<<"Unknown request ---
MAKE-QUEUE"<<endl;
exit(1);
return(makeList());
};
return(dispatch);
}
const
Queue makeQueue(void)
{
return(makeQueueDispatch(makeList()));
}
const
bool isEmptyQueue(const Queue& queue)
{return(executable<bool>
(queue(makeLeaf("empty-queue?")))());}
const
List frontQueue(const Queue& queue)
{return(executable<List>
(queue(makeLeaf("front-queue")))());}
const
Queue insertfQueue(const Queue& queue, const List& item)
{
executable<List,List>
(queue(makeLeaf("insert-queue!")))(item);
return(queue);
}
const
Queue deletefQueue(const Queue& queue)
{
executable<List>
(queue(makeLeaf("delete-queue!")))();
return(queue);
}
void
printQueue(const Queue& queue)
{cout<<listString(executable<List>(queue(makeLeaf("get-queue")))());}
//---------abstraction
barrier---------
int
main(int argc, char** argv)
{
cout<<"Excersize
3.22:"<<endl;
const auto q1(makeQueue());
printQueue(q1);cout<<endl;
printQueue(insertfQueue(q1,makeLeaf("a")));cout<<endl;
printQueue(insertfQueue(q1,makeLeaf("b")));cout<<endl;
printQueue(insertfQueue(q1,makeLeaf("c")));cout<<endl;
printQueue(deletefQueue(q1));cout<<endl;
printQueue(deletefQueue(q1));cout<<endl;
printQueue(insertfQueue(q1,makeLeaf("d")));cout<<endl;
printQueue(deletefQueue(q1));cout<<endl;
printQueue(deletefQueue(q1));cout<<endl;
return(0);
}
----
出力
----
Excersize
3.22:
()
('a)
('a
'b)
('a
'b 'c)
('b
'c)
('c)
('c
'd)
('d)
()
0 件のコメント :
コメントを投稿