新人教育用?ファイルシステムもどき

書いてて嫌になった。
その前にcygwin g++ではstd::tr1(::shared_ptr)が(まだ)使えないということで嫌になりかけてた。
ということで途中やり。
shared_ptrはやはりtypedefした方がいいのか。


そして電気回路基礎の宿題をやってご褒美と言わんばかりに東方をやる・・・。

#include <iostream>
#include <string>
#include <memory>
#include <vector>

using namespace std;
using namespace std::tr1;

struct FileElement {
	typedef vector<shared_ptr<FileElement> > file_list_t;

	bool isDir;
	string name;
	shared_ptr<FileElement> parent;
	file_list_t childs;

	FileElement(bool isDir_, const string &name_, shared_ptr<FileElement> parent_) :
	isDir(isDir_), name(name_), parent(parent_) {}
	shared_ptr<FileElement> search(const string &name){
		for(file_list_t::iterator it=childs.begin(); it!=childs.end(); ++it){
			if((*it)->name == name){
				return *it;
			}
		}
		return shared_ptr<FileElement>();
	}
	string createFullPath(){
		if(parent){
			string result = parent->createFullPath();
			result += name;
			result += "/";
			result.resize(result.size() - 1);
			return result;
		}
		else{
			return string("/");
		}
	}
private:
	FileElement(const FileElement &);
};

int main(){
	shared_ptr<FileElement> current(new FileElement(true, "", shared_ptr<FileElement>()));
	string cmd;
	while(1){
		cin >> cmd;
		if(cmd == "exit"){
			break;
		}
		else if(cmd == "pwd"){
			cout << current->createFullPath() << endl;
		}
		else if(cmd == "ls"){
			for(
				FileElement::file_list_t::iterator it = current->childs.begin();
				it != current->childs.end();
				++it
			){
				cout << (*it)->name << " " << ((*it)->isDir ? "(directory)" : "(file)") <<  endl;
			}
		}
		else if(cmd == "cd"){
			string name;
			cin >> name;
			if(name == ".."){
				if(current->parent){
					current = current->parent;
				}
				else{
					cout << ".. does not exists" << endl;
				}
			}
			else{
				shared_ptr<FileElement> dir = current->search(name);
				if(dir){
					if(dir->isDir){
						current = dir;
					}
					else{
						cout << name << " is not directory" << endl;
					}
				}
				else{
					cout << name << " does not exists" << endl;
				}
			}
		}
		else if(cmd == "mkdir"){
			string name;
			cin >> name;
			if(current->search(name)){
				cout << name << " already exists" << endl;
			}
			else{
				shared_ptr<FileElement> newDir(new FileElement(true, name, current));
				current->childs.push_back(newDir);
			}
		}
		else if(cmd == "touch"){
			string name;
			cin >> name;
			if(current->search(name)){
				cout << name << " already exists" << endl;
			}
			else{
				shared_ptr<FileElement> newFile(new FileElement(false, name, current));
				current->childs.push_back(newFile);
			}
		}
		else if(cmd == "rmdir"){
			
		}
		else if(cmd == "rm"){
			
		}
		else{
			cout << "Invalid command: " << cmd << endl;
		}
		cout << endl;
	}
	return 0;
}