MoReFEM
|
Class used to manage directories in MoReFEM. More...
#include <Directory.hpp>
Public Types | |
using | self = Directory |
Alias to the type of the class. | |
using | unique_ptr = std::unique_ptr<self> |
Smart pointer to hold it. | |
using | const_unique_ptr = std::unique_ptr<const self> |
Smart pointer to hold it. | |
Public Member Functions | |
const std::string & | GetPath () const noexcept |
Get the underlying Unix path. | |
File | AddFile (std::string_view filename) const |
Define path to a file in the directory. | |
behaviour | GetBehaviour () const noexcept |
Returns the behaviour. | |
void | SetBehaviour (behaviour new_behaviour, const std::source_location location=std::source_location::current()) |
Changes the behaviour. | |
const Wrappers::Mpi & | GetMpi () const noexcept |
Accessor to Mpi object (if relevant). | |
bool | IsMpi () const noexcept |
Whether mpi is considered or not. | |
bool | IsWithRank () const noexcept |
Whether a rank was given in construction. | |
bool | DoExist () const noexcept |
Tells whether the folder exists on the filesystem and is properly a directory. | |
void | Remove (const std::source_location location=std::source_location::current()) |
Remove the directory on disk. | |
void | AddSubdirectory (std::string_view subdirectory) |
Modify current directory so that it points to a subdirectory. | |
const std::filesystem::directory_entry & | GetDirectoryEntry () const noexcept |
Constant accessor to the underlying std::filesystem::directory_entry object. | |
void | ActOnFilesystem (const std::source_location location=std::source_location::current()) const |
The method which will enact on the filesystem what has been set in the object. | |
Special members. | |
Directory (const Wrappers::Mpi &mpi, const std::filesystem::path &path, behaviour directory_behaviour, add_rank do_add_rank=add_rank::yes, const std::source_location location=std::source_location::current()) | |
Constructor. | |
Directory (const std::filesystem::path &path, behaviour directory_behaviour, const std::source_location location=std::source_location::current()) | |
Simple constructor: no mpi involved - so no rank whatsoever added. | |
Directory (const Directory &parent_directory, std::filesystem::path &&subdirectory, std::optional< behaviour > directory_behaviour=std::nullopt, const std::source_location location=std::source_location::current()) | |
Constructor of a Directory which is a subdirectory on an already existing parent_directory. | |
template<class StringT > | |
Directory (const Directory &parent_directory, std::vector< StringT > &&layers, std::optional< behaviour > directory_behaviour=std::nullopt, const std::source_location location=std::source_location::current()) | |
Constructor of a Directory which is several layers of directories inside an already existing parent_directory. | |
~Directory ()=default | |
Destructor. | |
Directory (const Directory &rhs)=default | |
The copy constructor. | |
Directory (Directory &&rhs)=default | |
The move constructor. | |
Directory & | operator= (const Directory &rhs)=delete |
The (copy) operator=. | |
Directory & | operator= (Directory &&rhs)=delete |
The (move) operator=. | |
Private Member Functions | |
std::filesystem::directory_entry & | GetNonCstDirectoryEntry () noexcept |
Non constant accessor to the underlying std::filesystem::directory_entry object. | |
void | CollectAnswer (const std::source_location location=std::source_location::current()) const |
Helper method for the 'ask' behaviour. | |
const Wrappers::Mpi * | GetMpiPtr () const noexcept |
Accessor to Mpi pointer - required to define some constructors. | |
Private Attributes | |
std::filesystem::directory_entry | directory_entry_ |
Path of the directory. | |
const Wrappers::Mpi *const | mpi_ |
Mpi object. | |
behaviour | directory_behaviour_ |
What to do at the construction of the Directory object. | |
const bool | with_rank_ |
Whether the rank was given in construction. | |
Class used to manage directories in MoReFEM.
This class is built upon std::filesystem, but as I am not fond of the API provided in the STL I encapsulated it here.
Among the thing I don't like in std::filesystem:
You need to call refresh if you want the information to be up-to-date, but this is a non constant method... meaning you need to use non constant references for your filesystem-related objects!
The latter is the reason directory_entry_ data attribute is mutable: I want to be able to refresh properly under the hood but indicate clearly the filesystem object is not to be manipulated carelessly.
Moreover, this Directory class is also used to deal properly with the parallel nature of the library: we do not want to introduce race conditions when we want to create a directory, and we don't want either to make assumption upon the nature of the filesystem used in parallel (e.g. does each rank write on the same filesystem or on a different one?)
A simple way to do so which alleviate many problems is simply to automatically add a subdirectory indicating the rank; the convention in MoReFEM is to simply call it Rank_i where i is the rank. This way, each rank manage its outputs as it wishes.
Of course, it is not always what we want: for input data there is not much sense doing this. For some behaviour such as read or ignore, it is therefore possible to use in some constructors an argument to specify you do not want to extend with such Rank subdir your underlying path.
It can't be done for all behaviour: we really want to force users to use the safety net we provided within the class. If you really wat to circumvent it (might be the case for some tests, but please really don't do that in a model...) you may use the STL filesystem :
You may then benefit from Directory API such as AddFile() method,
Alias to the type of the class.
|
explicit |
Constructor.
[in] | mpi | Mpi object which knows the rank of the processor, the total number of processors, etc... |
[in] | directory_behaviour | Behaviour of the directory, among: |
Remember that Directory constructor never acts directly on the filesystem; you need to call ActOnFilesystem method if you want an action on the filesystem (typically create a directory).
[in] | path | Unix path of the directory. |
[in] | do_add_rank | Whether a "Rank_" part is added to the path. |
[in] | location | STL object with relevant information about the calling site (usually to help when an exception is thrown. |
|
explicit |
Simple constructor: no mpi involved - so no rank whatsoever added.
This constructor can only be used with 'read' and 'ignore' policy (this evacuates race conditions and management on whether each rank is on the same filesystem or not).
[in] | directory_behaviour | Behaviour of the directory, among: |
Remember that Directory constructor never acts directly on the filesystem; you need to call ActOnFilesystem method if you want an action on the filesystem (typically create a directory).
[in] | path | Path of the directory. Will be adjusted to match your OS filesystem. |
[in] | location | STL object with relevant information about the calling site (usually to help when an exception is thrown. |
|
explicit |
Constructor of a Directory which is a subdirectory on an already existing parent_directory.
[in] | subdirectory | Name of the subdirectory relative to parent_directory. |
[in] | parent_directory | The directory into which the new one is created (or read - depends on behaviour). The constructed directory takes the same attributes than its parent directory - except obviously for the path. |
[in] | directory_behaviour | Directory behaviour; if nullopt the behaviour of the parent directory is used (you should stick with this choice most of the time), |
[in] | location | STL object with relevant information about the calling site (usually to help when an exception is thrown. |
|
explicit |
Constructor of a Directory which is several layers of directories inside an already existing parent_directory.
[in] | layers | Names of the layers of subdirectories. For instance if { "Foo", "Bar"}, it will create inside parent_directory the subdirectory "Foo/Bar/". |
[in] | parent_directory | The directory into which the new one is created (or read - depends on behaviour). The constructed directory takes the same attributes than its parent directory - except obviously for the path. |
[in] | directory_behaviour | Directory behaviour; if nullopt the behaviour of the parent directory is used (you should stick with this choice most of the time), |
StringT | Type of subdirectory, which may actually be anything for which operator<< has been overloaded (avoid nonetheless values with spaces inside...) |
[in] | location | STL object with relevant information about the calling site (usually to help when an exception is thrown. |
|
default |
The copy constructor.
[in] | rhs | The object from which the construction occurs. |
|
default |
The move constructor.
[in] | rhs | The object from which the construction occurs. |
The (copy) operator=.
[in] | rhs | The object from which the affectation occurs. |
The (move) operator=.
[in] | rhs | The object from which the affectation occurs. |
File MoReFEM::FilesystemNS::Directory::AddFile | ( | std::string_view | filename | ) | const |
Define path to a file in the directory.
[in] | filename | Name of the file. |
void MoReFEM::FilesystemNS::Directory::SetBehaviour | ( | behaviour | new_behaviour, |
const std::source_location | location = std::source_location::current() ) |
Changes the behaviour.
[in] | new_behaviour | As written on the tag... |
[in] | location | STL object with relevant information about the calling site (usually to help when an exception is thrown. |
void MoReFEM::FilesystemNS::Directory::Remove | ( | const std::source_location | location = std::source_location::current() | ) |
Remove the directory on disk.
[in] | location | STL object with relevant information about the calling site (usually to help when an exception is thrown. |
void MoReFEM::FilesystemNS::Directory::AddSubdirectory | ( | std::string_view | subdirectory | ) |
Modify current directory so that it points to a subdirectory.
[in] | subdirectory | Name of the subdirectory layer that will hence be pointed by current object. |
void MoReFEM::FilesystemNS::Directory::ActOnFilesystem | ( | const std::source_location | location = std::source_location::current() | ) | const |
The method which will enact on the filesystem what has been set in the object.
For instance, if behaviour_ is behaviour::create the directory will be created on the filesystem (or STL will throw an exception).
[in] | location | STL object with relevant information about the calling site (usually to help when an exception is thrown. |
|
private |
Helper method for the 'ask' behaviour.
This behaviour requires inter-processor communication: each rank must tell root processor whether the directory already exist or not, and if some do root processor must ask the user what to do. Then it musts transmit back answers to each rank, which then must take action.
[in] | location | STL object with relevant information about the calling site (usually to help when an exception is thrown. |
|
mutableprivate |
Path of the directory.
The 'mutable' is due to a quirk in STL I dislike: some methods of std::filesystem::directory_entry such as exists may provide a wrong answer if refresh() is not called first... but the latter is non constant. To circumvent the potential wrong answer I this need to call refresh() first, but aside from that the methods such as DoExist() are morally const...
|
private |
What to do at the construction of the Directory object.
Options are:
Remember that Directory constructor never acts directly on the filesystem; you need to call ActOnFilesystem method if you want an action on the filesystem (typically create a directory).