Last active
June 16, 2016 04:05
-
-
Save macrat/f77ab7213ff31527f1892beb3a2cff7e to your computer and use it in GitHub Desktop.
pythonでもiostreamを実装出来るんじゃないだろうか。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import enum | |
| import functools | |
| import sys | |
| class Align(enum.Enum): | |
| left = lambda w, c, x: str(x) + c*(w-len(str(x))) | |
| right = lambda w, c, x: c*(w-len(str(x))) + str(x) | |
| @classmethod | |
| def __internal(cls, w, c, x): | |
| try: | |
| if x < 0: | |
| return '-' + c*(w-len(str(x))) + str(-x) | |
| except TypeError as e: | |
| pass | |
| return cls.right(w, c, x) | |
| internal = __internal | |
| class OStream: | |
| def __init__(self, f): | |
| self.__f = f | |
| self.basefield = None | |
| self.showbase = False | |
| self.fill = ' ' | |
| self.align = Align.right | |
| def _preprocess(self, x): | |
| if callable(self.basefield): | |
| try: | |
| x = self.basefield(x) | |
| if not self.showbase: | |
| x = x[2:] | |
| except TypeError: | |
| pass | |
| return x | |
| def __lshift__(self, x): | |
| if callable(x): | |
| return x(self) | |
| x = self._preprocess(x) | |
| self.__f.write(str(x)) | |
| return self | |
| def _flush(self): | |
| self.__f.flush() | |
| class ManipulatorBase: | |
| def __init__(self, stream): | |
| self._stream = stream | |
| @property | |
| def basefield(self): | |
| return self._stream.basefield | |
| @basefield.setter | |
| def basefield(self, x): | |
| self._stream.basefield = x | |
| @property | |
| def showbase(self): | |
| return self._stream.showbase | |
| @showbase.setter | |
| def showbase(self, x): | |
| self._stream.showbase = x | |
| @property | |
| def fill(self): | |
| return self._stream.fill | |
| @fill.setter | |
| def fill(self, x): | |
| self._stream.fill = x | |
| @property | |
| def align(self): | |
| return self._stream.align | |
| @align.setter | |
| def align(self, x): | |
| self._stream.align = x | |
| def _flush(self): | |
| self._stream._flush() | |
| def _preprocess(self, x): | |
| return self._stream._preprocess(x) | |
| def __lshift__(self, x): | |
| if callable(x): | |
| return x(self) | |
| x = self._preprocess(x) | |
| return self._stream << self._process(x) | |
| def _process(self, x): | |
| raise NotImplemented('please override it') | |
| def manipulator(func): | |
| class c(ManipulatorBase): | |
| def __init__(self, stream): | |
| super().__init__(stream) | |
| def _process(self, x): | |
| return func(x) | |
| @functools.wraps(func) | |
| def f(stream): | |
| return c(stream) | |
| return f | |
| def flush(stream): | |
| return stream._flush() | |
| def endl(stream): | |
| return stream << '\n' << flush | |
| def ends(stream): | |
| return stream << '\0' | |
| hex_ = hex | |
| def hex(stream): | |
| stream.basefield = hex_ | |
| return stream | |
| oct_ = oct | |
| def oct(stream): | |
| stream.basefield = oct_ | |
| return stream | |
| bin_ = bin | |
| def bin(stream): | |
| stream.basefield = bin_ | |
| return stream | |
| def dec(stream): | |
| stream.basefield = None | |
| return stream | |
| def showbase(stream): | |
| stream.showbase = True | |
| return stream | |
| def noshowbase(stream): | |
| stream.showbase = False | |
| return stream | |
| def setw(width): | |
| class c(ManipulatorBase): | |
| def __init__(self, stream): | |
| super().__init__(stream) | |
| def _process(self, x): | |
| return self._stream.align(width, self._stream.fill, x) | |
| def _setw(stream): | |
| return c(stream) | |
| return _setw | |
| def setfill(char): | |
| def f(stream): | |
| stream.fill = char | |
| return stream | |
| return f | |
| def right(stream): | |
| stream.align = Align.right | |
| return stream | |
| def left(stream): | |
| stream.align = Align.left | |
| return stream | |
| def internal(stream): | |
| stream.align = Align.internal | |
| return stream | |
| cout = OStream(sys.stdout) | |
| if __name__ == '__main__': | |
| cout << "hello" << endl; | |
| cout << "this is a " << internal << setw(4) << -24 << " " << left << setfill("-") << setw(6) << "test" << " " << 2 << endl; | |
| cout << showbase << "hex: " << hex << 24 << ", oct: " << oct << 24 << ", bin: " << bin << 24 << ", dec: " << dec << 24 << endl; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment