codepad
[
create a new paste
]
login
|
about
Language:
C
C++
D
Haskell
Lua
OCaml
PHP
Perl
Plain Text
Python
Ruby
Scheme
Tcl
import std.stdio, std.string; // 文字列のエスケープを行う。 string c_escape(string s) { string t; foreach(c; s) { switch(c) { case '"': t ~= "\\\""; break; case '\\': t ~= "\\\\"; break; case '\a': t ~= "\\a"; break; case '\b': t ~= "\\b"; break; case '\f': t ~= "\\f"; break; case '\n': t ~= "\\n"; break; case '\r': t ~= "\\r"; break; case '\t': t ~= "\\t"; break; case '\v': t ~= "\\v"; break; case '\0': t ~= "\\0"; break; default: if (c <= 0x7F) { t ~= c; } else { t ~= "\\x"; t ~= hexdigits[c >>> 4]; t ~= hexdigits[c & 0xF]; } } } return t; } // 基底クラス。 abstract class RbObject { /*C++と違って、クラスはデフォルトpublic*/ // オブジェクトID。 int m_id; //public! // パス(インデックスリスト)。 size_t[] m_path; //public! // 次のオブジェクトID。 static int s_idNext = 0; //public! protected: this() { m_id = s_idNext; s_idNext++; } public: // 出力する。 version(none) abstract void write(); //toString()をオーバーライドしよう version(none) void writeln() { write(); writef("\n"); } // 複製を作る。 abstract RbObject clone(); // 型名を返す。 version(none) abstract string type(); //.classinfo.nameを使おう // 比較する。 abstract bool opEquals(RbObject); abstract int opCmp(RbObject o); // オブジェクトID。 int id() { return m_id; } void id(int id) { m_id = id; } // パス。 size_t[] path() { return m_path; } void path(size_t[] p) { m_path = p; } void setRoot() { size_t[] a; path(a); } } // 整数クラス。 class RbInteger : public RbObject { int m_i; //public! public: this(int i) { super(); m_i = i; } // int型へのキャスト。 int opCast() { return m_i; } // 比較。 bool opEquals(RbInteger i) { return opEquals(i.m_i); } version(none) bool opEquals(RbString) { //不要 return false; } version(none) bool opEquals(RbArray) { //不要 return false; } bool opEquals(int i) { return m_i == i; } bool opEquals(RbObject o) { //この重複コードどうしようか・・・ if (this.classinfo.name == o.classinfo.name) return false; return opEquals(cast(typeof(this))o); } // RbInteger < RbString < RbArray この定義は好ましくない! int opCmp(RbInteger i) { return opCmp(i.m_i); } int opCmp(RbString) { return -1; } int opCmp(RbArray) { return -1; } int opCmp(int i) { if (m_i < i) return -1; if (m_i > i) return 1; return 0; } int opCmp(RbObject o) { //この重複コードもどうしようか・・・w string oname = o.classinfo.name; if(oname == RbInteger.classinfo.name) { return opCmp(cast(RbInteger)o); } else if(oname == RbString.classinfo.name) { return opCmp(cast(RbString)o); } else if(oname == RbArray.classinfo.name) { return opCmp(cast(RbArray)o); } else { assert(false); } } version(D_Version2) //D1非対応のコード { // 2項演算子。 RbInteger opBinary(string s)(RbInteger i) { return opBinary(s)(i.m_i); } RbInteger opBinary(string s)(int i) { static if (s == "+") { return new RbInteger(m_i + i); } static if (s == "-") { return new RbInteger(m_i - i); } static if (s == "*") { return new RbInteger(m_i * i); } static if (s == "/") { return new RbInteger(m_i / i); } static if (s == "%") { return new RbInteger(m_i % i); } } } // 代入。 RbInteger opAssign(int i) { m_i = i; return this; } RbInteger opOpAssign(string s)(RbInteger i) { return opOpAssign(s)(i.m_i); } RbInteger opOpAssign(string s)(int i) { static if (s == "+=") { m_i += i; } static if (s == "-=") { m_i -= i; } static if (s == "*=") { m_i *= i; } static if (s == "/=") { m_i /= i; } static if (s == "%=") { m_i %= i; } return this; } override string toString() { return format(m_i); } RbInteger clone() { return new RbInteger(m_i); } } // 文字列クラス。 class RbString : public RbObject { string m_s; //public! public: this(string s) { super(); m_s = s; } // string型へのキャスト。 string opCast() { return m_s; } // 比較。 version(none) bool opEquals(RbInteger i) { return false; } bool opEquals(RbString s) { return opEquals(s.m_s); } version(none) bool opEquals(RbArray) { return false; } bool opEquals(string s) { return m_s == s; } bool opEquals(RbObject o) { if (this.classinfo.name == o.classinfo.name) return false; return opEquals(cast(typeof(this))o); } // RbInteger < RbString < RbArray int opCmp(RbInteger) { return 1; } int opCmp(RbString s) { return opCmp(s.m_s); } int opCmp(RbArray) { return -1; } int opCmp(string s) { if (m_s < s) return -1; if (m_s > s) return 1; return 0; } int opCmp(RbObject o) { string oname = o.classinfo.name; if(oname == RbInteger.classinfo.name) { return opCmp(cast(RbInteger)o); } else if(oname == RbString.classinfo.name) { return opCmp(cast(RbString)o); } else if(oname == RbArray.classinfo.name) { return opCmp(cast(RbArray)o); } else { assert(false); } } // インデックス演算子。 char opIndex(size_t i) { return m_s[i]; } char opIndexAssign(char c, size_t i) { m_s[i] = c; return m_s[i]; } // スライス演算子。 RbString opSlice(size_t i, size_t j) { return new RbString(m_s[i .. j]); } void opSliceAssign(char c) { m_s[] = c; } void opSliceAssign(char c, size_t i, size_t j) { m_s[i .. j] = c; } // 代入。 RbString opAssign(string s) { m_s = s; return this; } RbString opOpAssign(string op)(RbString s) { return opOpAssign(op)(s.m_s); } RbString opOpAssign(string op)(string s) { static if (op == "~=") { m_s ~= s; } return this; } override string toString() { return format("\"" ~ c_escape(m_s) ~ "\""); } RbString clone() { return new RbString(m_s); } } // 配列クラス。 class RbArray : public RbObject { RbObject[] m_objects; //public! public: this() { super(); } this(RbObject[] objects ...) { super(); m_objects = objects; } // 比較。 version(none) bool opEquals(RbInteger) { return false; } version(none) bool opEquals(RbString) { return false; } bool opEquals(RbArray ra) { if (m_objects.length != ra.m_objects.length) return false; size_t len = m_objects.length; for(size_t i = 0; i < len; i++) { if (m_objects[i] != ra.m_objects[i]) return false; } return true; } bool opEquals(RbObject o) { if (this.classinfo.name == o.classinfo.name) return false; return opEquals(cast(typeof(this))o); } // RbInteger < RbString < RbArray int opCmp(RbInteger) { return 1; } int opCmp(RbString) { return 1; } int opCmp(RbArray ra) { size_t len; if (m_objects.length < ra.m_objects.length) len = m_objects.length; else len = ra.m_objects.length; for(size_t i = 0; i < len; i++) { if (m_objects[i] > ra.m_objects[i]) return 1; if (m_objects[i] < ra.m_objects[i]) return -1; } return cast(int)m_objects.length - cast(int)ra.m_objects.length; } int opCmp(RbObject o) { string oname = o.classinfo.name; if(oname == RbInteger.classinfo.name) { return opCmp(cast(RbInteger)o); } else if(oname == RbString.classinfo.name) { return opCmp(cast(RbString)o); } else if(oname == RbArray.classinfo.name) { return opCmp(cast(RbArray)o); } else { assert(false); } } // インデックス演算子。 RbObject opIndex(size_t i) { return m_objects[i]; } RbObject opIndexAssign(RbObject w, size_t i) { m_objects[i] = w; return m_objects[i]; } // スライス演算子。 RbObject[] opSlice() { return m_objects; } RbObject[] opSlice(size_t i, size_t j) { return m_objects[i .. j]; } void opSliceAssign(RbObject o) { m_objects[] = o; } void opSliceAssign(RbObject o, size_t i, size_t j) { m_objects[i .. j] = o; } // パス(インデックスリスト)からオブジェクトを得る。 RbObject objectFromPath(size_t[] indexList ...) { RbObject o = null; RbArray array = this; size_t i = 0; if (i < indexList.length) { for(;;) { o = array[indexList[i]]; i++; if (i == indexList.length) break; array = cast(RbArray)o; } } return o; } // パス(インデックスリスト)から整数を得る。 RbInteger integerFromPath(size_t[] indexList ...) { return cast(RbInteger)objectFromPath(indexList); } // パス(インデックスリスト)から文字列を得る。 RbString stringFromPath(size_t[] indexList ...) { return cast(RbString)objectFromPath(indexList); } // パス(インデックスリスト)から配列を得る。 RbArray arrayFromPath(size_t[] indexList ...) { return cast(RbArray)objectFromPath(indexList); } override string toString() { char[] str; str ~= "["; if (m_objects.length > 0) { str ~= m_objects[0].toString(); for(size_t i = 1; i < m_objects.length; i++) { str ~= ", "; str ~= m_objects[i].toString(); } } str ~= "]"; return cast(string) str; } RbArray clone() { RbObject[] objects; objects.length = m_objects.length; for(size_t i = 0; i < m_objects.length; i++) { objects[i] = m_objects[i].clone(); } return new RbArray(objects); } size_t length() { return m_objects.length; } // ソートする。 void sort() { if (m_objects.length <= 1) return; for(size_t i = 0; i < m_objects.length; i++) { if (m_objects[i].classinfo.name == RbArray.classinfo.name) { (cast(RbArray)m_objects[i]).sort(); } } for(size_t i = 0; i < m_objects.length - 1; i++) { for(size_t j = i + 1; j < m_objects.length; j++) { if (m_objects[i] > m_objects[j]) { RbObject tmp = m_objects[i]; m_objects[i] = m_objects[j]; m_objects[j] = tmp; } } } } // パス。 void path(size_t[] p) { super.path(p); for(size_t i = 0; i < m_objects.length; i++) { m_objects[i].path(p ~ i); } } } // メイン関数。 int main() { // [34, "test2", 12, ["test", 324], [11]] RbArray ra = new RbArray( new RbInteger(34), new RbString("test2"), new RbInteger(12), new RbArray(new RbString("test"), new RbInteger(324)), new RbArray(new RbInteger(11)) ); writef("newed: "); writefln(ra); RbArray ra2 = ra.clone(); writef("cloned: "); writefln(ra2); delete ra; writef("[3, 1]: "); writefln(ra2.objectFromPath(3, 1)); ra2.sort(); writef("sorted: "); writefln(ra2); delete ra2; writefln("ending"); fflush(stdout); return 0; }
Private
[
?
]
Run code
Submit