Come on, it's not OO, it's normal procedural C functions like any other.
Most everyone calls this an OO design in C:
https://lwn.net/Articles/444910/https://en.wikipedia.org/wiki/GObjectInside PhysFS literally does (in C, by hand) literally same things like C++ does: a vtable of pointers for methods handling different IO types and archive types, members per concrete type, all hidden behind a common interface from physfs.h, etc.
As for what to do when a function fails, I'd say you should throw an exception: if a file is missing a value you expect it's surely corrupt and you'll have to deal with that. Or as you said yourself you could easily return an int bool pair, or you could return an optional. Plenty of ways to deal with erroneous calls.
Sure. But that's opinionated and mismatches what SFML (and many others) does now and what many people prefer (error codes, some kind of 'optional' template type).
You'd set the endianness for the filesystem because as the developer you know what endianness your data files are. So when the filesystem opens a file for reading, it can automatically convert from that to native, or vice versa for writing.
But you can have files of different endianess. Png and other 'portable' types has big, many Windows originating file types have little. There are even file formats that have some fields in their headers or something that say whether or not to read the ints in that file as big or little endian and you don't know which one it is until you parse the headers so your idea totally dies with such a file.
VirtualFilesystem<VFS_BIG_ENDIAN> filesystem();
filesystem.AddDirectory("search/this/path");
auto file = filesystem.GetFile("filename.ext");
auto num = file.ReadUInt16();
You need to remove () from after filesystem (most vexing parse is the name of this error/compiler mistake).
Anyway - this is crazy. Not only can you not read in another endian within one FS, you need to keep in mind (hundreds of lines away in another function) what kind of FS has made your file, to know what kind of read (big or little) you just did, all so you can write readUInt16 instead of readUInt16BE. You also can't write a function taking VirtualFilesystem easily (forcing everyone to use templates everywhere is not 'easily') because endianess is baked into the FS type for 0 real reason.
And that's more convenient than 10 plain C functions... And the only other 'improvement' over C here is that methods are obj.method and not method(obj) or that you can use std::string too without c_str.
It makes literally no sense to have endianess set on filesystem or even file, when it can (and is) be specified in each function with just few letters like BE, LE, Big, Little. That way you don't have to look around anywhere to file or filesystem constructor or something to find out what endianess you're working with.
IF you think you need these features then you can easily wrap Phys yourself to try, but I think you'll just get burned when you have two files with different endian (big endian is 'portable' or 'network' one so it gets used in some formats, but little one is native to Windows/Intel so its in lots of Windows file formats too) or start forgetting what endian your program is using while in middle of some file parsing or waste more time on this than you'll ever save by not writing func(obj) anymore but obj.method().
As far as duplicated functionality between SFML and standards, that's all been well-discussed here and in related topics: https://en.sfml-dev.org/forums/index.php?topic=21571.0
Nowhere in there did anyone suggest removing (
) sf::Vector2. We/they are debating removing the 'shortcuts' overloads in some classes (there is setPosition(x, y) and setPosition(vector)) which are there to not force user to keep doing someFunction(sf::Vector2f(x, y)) but with modern C++ they can do someFunction({x, y}) instead which will do the right thing (make a vector) so some people want the shortcut that takes two singular arguments removed (I don't but it's not a big deal and I write sf::Vector2f(x, y) all the time for clarity in cases like these). No one is removing sf::Vector2f itself, there is no 'replacement' for it in C++ or standard libraries of any version.
And the word duplicated doesn't appear in this thread even once.
I'm seriously done with this now, I feel like I took troll bait for even talking to someone who wants to force all files in an application to have same endianess to not add BE or LE to a readUint16 function name, finds it hard to use (?) struct Version {int major; int minor; int patch;} or says that C style strings (that are not your responsibility to allocate or free) are hard to use along std::string or that typedefs (that you can ignore and use std::intXX_t on your code) or void * pointer for a memory buffer are weird or complex to use from C++. And to 'fix' these 'problems' we need a VFS in SFML that either wraps or reimplements PhysFS and then add this silly Filesystem<BIG> interface on top of it.
Or says we said we're gonna remove sf::Vector2