Replace IOError with std::error_code
Using std::error_code is more convenient, but we will need to make sure we internally get (int, char *) from a TLS (via a getLastError() method when a method returns unsuccessfully) and then convert to std::error_code in inline methods so we are not hit by ABI incompatibilities when mixing debug/release builds and/or compiler versions.