| 297 | // ============================================================================ |
| 298 | |
| 299 | class fstream { |
| 300 | private: |
| 301 | filebuf_ptr mHandle; |
| 302 | fl::size_t mLastRead; |
| 303 | bool mGood; |
| 304 | bool mEof; |
| 305 | bool mFail; |
| 306 | int mLocalError; |
| 307 | |
| 308 | void updateState() { |
| 309 | if (mHandle && mHandle->is_open()) { |
| 310 | mEof = mHandle->is_eof(); |
| 311 | mFail = mHandle->has_error() || (mLocalError != 0); |
| 312 | mGood = !mEof && !mFail; |
| 313 | } else { |
| 314 | mGood = false; |
| 315 | mEof = false; |
| 316 | mFail = true; |
| 317 | } |
| 318 | } |
| 319 | |
| 320 | public: |
| 321 | fstream() FL_NOEXCEPT : mLastRead(0), mGood(false), mEof(false), mFail(true), mLocalError(0) {} |
| 322 | |
| 323 | explicit fstream(const char* path, ios::openmode mode = ios::in | ios::out); |
| 324 | |
| 325 | explicit fstream(filebuf_ptr handle); |
| 326 | |
| 327 | ~fstream() FL_NOEXCEPT; |
| 328 | |
| 329 | // Non-copyable |
| 330 | fstream(const fstream&) FL_NOEXCEPT = delete; |
| 331 | fstream& operator=(const fstream&) = delete; |
| 332 | |
| 333 | // Moveable |
| 334 | fstream(fstream&& other) FL_NOEXCEPT |
| 335 | : mHandle(other.mHandle), mLastRead(other.mLastRead), |
| 336 | mGood(other.mGood), mEof(other.mEof), mFail(other.mFail), |
| 337 | mLocalError(other.mLocalError) { |
| 338 | other.mHandle.reset(); |
| 339 | other.mLastRead = 0; |
| 340 | other.mGood = false; |
| 341 | other.mEof = false; |
| 342 | other.mFail = true; |
| 343 | other.mLocalError = 0; |
| 344 | } |
| 345 | |
| 346 | fstream& operator=(fstream&& other) FL_NOEXCEPT { |
| 347 | if (this != &other) { |
| 348 | close(); |
| 349 | mHandle = other.mHandle; |
| 350 | mLastRead = other.mLastRead; |
| 351 | mGood = other.mGood; |
| 352 | mEof = other.mEof; |
| 353 | mFail = other.mFail; |
| 354 | mLocalError = other.mLocalError; |
| 355 | other.mHandle.reset(); |
| 356 | other.mLastRead = 0; |