- Table of Contents
- Previous Chapter
- Next Chapter

# Chapter 4: Namespaces

## 4.1: Namespaces

Imagine a math teacher who wants to develop an interactive math program. For this program functions like `cos, sin, tan` etc. are to be used accepting arguments in degrees rather than arguments in radians. Unfortunately, the function name `cos` is already in use, and that function accepts radians as its arguments, rather than degrees.

Problems like these are usually solved by defining another name, e.g., the function name `cosDegrees` is defined. C++ offers an alternative solution through namespaces. Namespaces can be considered as areas or regions in the code in which identifiers may be defined. Identifiers defined in a namespace normally won't conflict with names already defined elsewhere (i.e., outside of their namespaces). So, a function `cos` (expecting angles in degrees) could be defined in a namespace `Degrees`. When calling `cos` from within `Degrees` you would call the `cos` function expecting degrees, rather than the standard `cos` function expecting radians.

### 4.1.1: Defining namespaces

Namespaces are defined according to the following syntax:

        namespace identifier
        {
            // declared or defined entities
            // (declarative region)
        }

The identifier used when defining a namespace is a standard C++ identifier.

Within the declarative region, introduced in the above code example, functions, variables, structs, classes and even (nested) namespaces can be defined or declared. Namespaces cannot be defined within a function body. However, it is possible to define a namespace using multiple namespace declarations. Namespaces are `open' meaning that a namespace `CppAnnotations` could be defined in a file `file1.cc` and also in a file `file2.cc`. Entities defined in the `CppAnnotations` namespace of files `file1.cc` and `file2.cc` are then united in one `CppAnnotations` namespace region. For example:

        // in file1.cc
        namespace CppAnnotations
        {
            double cos(double argInDegrees)
            {
                ...
            }
        }

        // in file2.cc
        namespace CppAnnotations
        {
            double sin(double argInDegrees)
            {
                ...
            }
        }

Both `sin` and `cos` are now defined in the same `CppAnnotations` namespace.

Namespace entities can be defined outside of their namespaces. This topic is discussed in section 4.1.4.1.

#### 4.1.1.1: Declaring entities in namespaces

Instead of defining entities in a namespace, entities may also be declared in a namespace. This allows us to put all the declarations in a header file that can thereupon be included in sources using the entities defined in the namespace. Such a header file could contain, e.g.,

        namespace CppAnnotations
        {
            double cos(double degrees);
            double sin(double degrees);
        }

#### 4.1.1.2: A closed namespace

Namespaces can be defined without a name. Such an anonymous namespace restricts the visibility of the defined entities to the source file defining the anonymous namespace.

Entities defined in the anonymous namespace are comparable to C's `static` functions and variables. In C++ the `static` keyword can still be used, but its preferred use is in `class` definitions (see chapter 7). In situations where in C static variables or functions would have been used the anonymous namespace should be used in C++.

The anonymous namespace is a closed namespace: it is not possible to add entities to the same anonymous namespace using different source files.

### 4.1.2: Referring to entities

Given a namespace and its entities, the scope resolution operator can be used to refer to its entities. For example, the function `cos()` defined in the `CppAnnotations` namespace may be used as follows:

        // assume CppAnnotations namespace is declared in the
        // following header file:
        #include <cppannotations>

        int main()
        {
            cout << "The cosine of 60 degrees is: " <<
                    CppAnnotations::cos(60) << '\n';
        }

This is a rather cumbersome way to refer to the `cos()` function in the `CppAnnotations` namespace, especially so if the function is frequently used. In cases like these an abbreviated form can be used after specifying a using declaration. Following

        using CppAnnotations::cos;  // note: no function prototype,
                                    // just the name of the entity
                                    // is required.

calling `cos` results in a call of the `cos` function defined in the `CppAnnotations` namespace. This implies that the standard `cos` function, accepting radians, is not automatically called anymore. To call that latter `cos` function the plain scope resolution operator should be used:

        int main()
        {
            using CppAnnotations::cos;
            ...
            cout << cos(60)         // calls CppAnnotations::cos()
                << ::cos(1.5)       // call the standard cos() function
                << '\n';
        }

A `using` declaration can have restricted scope. It can be used inside a block. The `using` declaration prevents the definition of entities having the same name as the one used in the `using` declaration. It is not possible to specify a `using` declaration for a variable `value` in some namespace, and to define (or declare) an identically named object in a block also containing a `using` declaration. Example:

        int main()
        {
            using CppAnnotations::value;
            ...
            cout << value << '\n';  // uses CppAnnotations::value
            int value;              // error: value already declared.
        }

#### 4.1.2.1: The `using' directive

A generalized alternative to the `using` declaration is the using directive:

        using namespace CppAnnotations;

Following this directive, all entities defined in the `CppAnnotations` namespace are used as if they were declared by `using` declarations.

While the `using` directive is a quick way to import all the names of a namespace (assuming the namespace has previously been declared or defined), it is at the same time a somewhat dirty way to do so, as it is less clear what entity is actually used in a particular block of code.

If, e.g., `cos` is defined in the `CppAnnotations` namespace, `CppAnnotations::cos` is going to be used when `cos` is called. However, if `cos` is not defined in the `CppAnnotations` namespace, the standard `cos` function will be used. The `using` directive does not document as clearly as the `using` declaration what entity will actually be used. Therefore use caution when applying the `using` directive.

Namespace declarations are context sensitive: when a `using namespace` declaration is specified inside a compound statement then the declaration is valid until the compound statement's closing curly brace has been encountered. In the next example a string `first` is defined without explicit specifying `std::string`, but once the compound statement has ended the scope of the `using namespace std` declaration has also ended, and so `std::` is required once again when defining `second`:

        #include <string>
        int main()
        {
            {
                using namespace std;
                string first;
            }
            std::string second;
        }

A `using namespace` directive cannot be used within the declaration block of a class- or enumeration-type. E.g., the following example won't compile:

        struct Namespace
        {
            using namespace std;      // won't compile
        };

#### 4.1.2.2: `Koenig lookup'

If Koenig lookup were called the `Koenig principle', it could have been the title of a new Ludlum novel. However, it is not. Instead it refers to a C++ technicality.

`Koenig lookup' refers to the fact that if a function is called without specifying its namespace, then the namespaces of its argument types are used to determine the function's namespace. If the namespace in which the argument types are defined contains such a function, then that function is used. This procedure is called the `Koenig lookup'.

As an illustration consider the next example. The function `FBB::fun(FBB::Value v)` is defined in the `FBB` namespace. It can be called without explicitly mentioning its namespace:

        #include <iostream>

        namespace FBB
        {
            enum Value        // defines FBB::Value
            {
                FIRST
            };

            void fun(Value x)
            {
                std::cout << "fun called for " << x << '\n';
            }
        }

        int main()
        {
            fun(FBB::FIRST);    // Koenig lookup: no namespace
                                // for fun() specified
        }
        /*
            generated output:
        fun called for 0
        */

The compiler is rather smart when handling namespaces. If `Value` in the `namespace FBB` would have been defined as `using Value = int` then `FBB::Value` would be recognized as `int`, thus causing the Koenig lookup to fail.

As another example, consider the next program. Here two namespaces are involved, each defining their own `fun` function. There is no ambiguity, since the argument defines the namespace and `FBB::fun` is called:

        #include <iostream>

        namespace FBB
        {
            enum Value        // defines FBB::Value
            {
                FIRST
            };

            void fun(Value x)
            {
                std::cout << "FBB::fun() called for " << x << '\n';
            }
        }

        namespace ES
        {
            void fun(FBB::Value x)
            {
                std::cout << "ES::fun() called for " << x << '\n';
            }
        }

        int main()
        {
            fun(FBB::FIRST);    // No ambiguity: argument determines
                                // the namespace
        }
        /*
            generated output:
        FBB::fun() called for 0
        */

Here is an example in which there is an ambiguity: `fun` has two arguments, one from each namespace. The ambiguity must be resolved by the programmer:

        #include <iostream>

        namespace ES
        {
            enum Value        // defines ES::Value
            {
                FIRST
            };
        }

        namespace FBB
        {
            enum Value        // defines FBB::Value
            {
                FIRST
            };

            void fun(Value x, ES::Value y)
            {
                std::cout << "FBB::fun() called\n";
            }
        }

        namespace ES
        {
            void fun(FBB::Value x, Value y)
            {
                std::cout << "ES::fun() called\n";
            }
        }

        int main()
        {
            //  fun(FBB::FIRST, ES::FIRST); ambiguity: resolved by
            //                              explicitly mentioning
            //                              the namespace
            ES::fun(FBB::FIRST, ES::FIRST);
        }
        /*
            generated output:
        ES::fun() called
        */

An interesting subtlety with namespaces is that definitions in one namespace may break the code defined in another namespace. It shows that namespaces may affect each other and that namespaces may backfire if we're not aware of their peculiarities. Consider the following example:

        namespace FBB
        {
            struct Value
            {};

            void fun(int x);
            void gun(Value x);
        }

        namespace ES
        {
            void fun(int x)
            {
                fun(x);
            }
            void gun(FBB::Value x)
            {
                gun(x);
            }
        }

Whatever happens, the programmer'd better not use any of the functions defined in the `ES` namespace, since that would result in infinite recursion. However, that's not the point. The point is that the programmer won't even be given the opportunity to call `ES::fun` since the compilation fails.

Compilation fails for `gun` but not for `fun`. But why is that so? Why is `ES::fun` flawlessly compiling while `ES::gun` isn't? In `ES::fun` `fun(x)` is called. As `x`'s type is not defined in a namespace the Koenig lookup does not apply and `fun` calls itself with infinite recursion.

With `ES::gun` the argument is defined in the `FBB` namespace. Consequently, the `FBB::gun` function is a possible candidate to be called. But `ES::gun` itself also is possible as `ES::gun`'s prototype perfectly matches the call `gun(x)`.

Now consider the situation where `FBB::gun` has not yet been declared. Then there is of course no ambiguity. The programmer responsible for the `ES` namespace is resting happily. Some time after that the programmer who's maintaining the `FBB` namespace decides it may be nice to add a function `gun(Value x)` to the `FBB` namespace. Now suddenly the code in the namespace `ES` breaks because of an addition in a completely other namespace (`FBB`). Namespaces clearly are not completely independent of each other and we should be aware of subtleties like the above. Later in the C++ Annotations (chapter 11) we'll return to this issue.

Koenig lookup is only used in the context of namespaces. If a function is defined outside of a namespace, defining a parameter of a type that's defined inside a namespace, and that namespace also defines a function with an identical signature, then the compiler reports an ambiguity when that function is called. Here is an example, assuming the abovementioned namespace `FBB` is also available:

        void gun(FBB::Value x);

        int main(int argc, char **argv)
        {
            gun(FBB::Value{});          // ambiguity: FBB::gun and ::gun can both
                                        // be called.
        }

### 4.1.3: The standard namespace

The `std` namespace is reserved by C++. The standard defines many entities that are part of the runtime available software (e.g., `cout, cin, cerr`); the templates defined in the Standard Template Library (cf. chapter 18); and the Generic Algorithms (cf. chapter 19) are defined in the `std` namespace.

Regarding the discussion in the previous section, `using` declarations may be used when referring to entities in the `std` namespace. For example, to use the `std::cout` stream, the code may declare this object as follows:

        #include <iostream>
        using std::cout;

Often, however, the identifiers defined in the `std` namespace can all be accepted without much thought. Because of that, one frequently encounters a `using` directive, allowing the programmer to omit a namespace prefix when referring to any of the entities defined in the namespace specified with the `using` directive. Instead of specifying `using` declarations the following `using` directive is frequently encountered: construction like

        #include <iostream>
        using namespace std;

Should a `using` directive, rather than `using` declarations be used? As a rule of thumb one might decide to stick to `using` declarations, up to the point where the list becomes impractically long, at which point a `using` directive could be considered.

Two restrictions apply to `using` directives and declarations:

- Programmers should not declare or define anything inside the `namespace std`. This is not compiler enforced but is imposed upon user code by the standard;
- `Using` declarations and directives should not be imposed upon code written by third parties. In practice this means that `using` directives and declarations should be banned from header files and should only be used in source files (cf. section 7.11.1).

### 4.1.4: Nesting namespaces and namespace aliasing

Namespaces can be nested. Here is an example:

        namespace CppAnnotations
        {
            int value;
            namespace Virtual
            {
                void *pointer;
            }
        }

The variable `value` is defined in the `CppAnnotations` namespace. Within the `CppAnnotations` namespace another namespace (`Virtual`) is nested. Within that latter namespace the variable `pointer` is defined. To refer to these variable the following options are available:

- The fully qualified names can be used. A fully qualified name of an entity is a list of all the namespaces that are encountered until reaching the definition of the entity. The namespaces and entity are glued together by the scope resolution operator:

      int main()
      {
          CppAnnotations::value = 0;
          CppAnnotations::Virtual::pointer = 0;
      }

- A `using namespace CppAnnotations` directive can be provided. Now `value` can be used without any prefix, but `pointer` must be used with the `Virtual::` prefix:

      using namespace CppAnnotations;

      int main()
      {
          value = 0;
          Virtual::pointer = 0;
      }

- A `using namespace` directive for the full namespace chain can be used. Now `value` needs its `CppAnnotations` prefix again, but `pointer` doesn't require a prefix anymore:

      using namespace CppAnnotations::Virtual;

      int main()
      {
          CppAnnotations::value = 0;
          pointer = 0;
      }

- When using two separate `using namespace` directives none of the namespace prefixes are required anymore:

      using namespace CppAnnotations;
      using namespace Virtual;

      int main()
      {
          value = 0;
          pointer = 0;
      }

- The same can be accomplished (i.e., no namespace prefixes) for specific variables by providing specific `using` declarations:

      using CppAnnotations::value;
      using CppAnnotations::Virtual::pointer;

      int main()
      {
          value = 0;
          pointer = 0;
      }

- A combination of `using namespace` directives and `using` declarations can also be used. E.g., a `using namespace` directive can be used for the `CppAnnotations::Virtual` namespace, and a `using` declaration can be used for the `CppAnnotations::value` variable:

      using namespace CppAnnotations::Virtual;
      using CppAnnotations::value;

      int main()
      {
          value = 0;
          pointer = 0;
      }

Following a `using namespace` directive all entities of that namespace can be used without any further prefix. If a single `using namespace` directive is used to refer to a nested namespace, then all entities of that nested namespace can be used without any further prefix. However, the entities defined in the more shallow namespace(s) still need the shallow namespace's name(s). Only after providing specific `using namespace` directives or `using` declarations namespace qualifications can be omitted.

When fully qualified names are preferred but a long name like

        CppAnnotations::Virtual::pointer

is considered too long, a namespace alias may be used:

        namespace CV = CppAnnotations::Virtual;

This defines `CV` as an alias for the full name. The variable `pointer` may now be accessed using:

        CV::pointer = 0;

A namespace alias can also be used in a `using namespace` directive or `using` declaration:

        namespace CV = CppAnnotations::Virtual;
        using namespace CV;

Nested namespace definitions

Starting with the C++17 standard, when nesting namespaces a nested namespace can directly be referred to using scope resolution operators. E.g.,

        namespace Outer::Middle::Inner
        {
            // entities defined/declared here are defined/declared in the Inner
            // namespace, which is defined in the Middle namespace, which is
            // defined in the Outer namespace
        }

#### 4.1.4.1: Defining entities outside of their namespaces

It is not strictly necessary to define members of namespaces inside a namespace region. But before an entity is defined outside of a namespace it must have been declared inside its namespace.

To define an entity outside of its namespace its name must be fully qualified by prefixing the member by its namespaces. The definition may be provided at the global level or at intermediate levels in the case of nested namespaces. This allows us to define an entity belonging to namespace `A::B` within the region of namespace `A`.

Assume the type `int INT8[8]` is defined in the `CppAnnotations::Virtual` namespace. Furthermore assume that it is our intent to define a function `squares`, inside the namespace
`CppAnnotations::Virtual` returning a pointer to `CppAnnotations::Virtual::INT8`.

Having defined the prerequisites within the `CppAnnotations::``Virtual` namespace, our function could be defined as follows (cf. chapter 9 for coverage of the memory allocation operator `new[]`):

        namespace CppAnnotations
        {
            namespace Virtual
            {
                void *pointer;

                using INT8 = int[8];

                INT8 *squares()
                {
                    INT8 *ip = new INT8[1];

                    for (size_t idx = 0; idx != sizeof(INT8) / sizeof(int); ++idx)
                        (*ip)[idx] = (idx + 1) * (idx + 1);

                    return ip;
                }
            }
        }

The function `squares` defines an array of one `INT8` vector, and returns its address after initializing the vector by the squares of the first eight natural numbers.

Now the function `squares` can be defined outside of the `CppAnnotations::``Virtual` namespace:

        namespace CppAnnotations
        {
            namespace Virtual
            {
                void *pointer;

                using INT8 = int[8];

                INT8 *squares();
            }
        }

        CppAnnotations::Virtual::INT8 *CppAnnotations::Virtual::squares()
        {
            INT8 *ip = new INT8[1];

            for (size_t idx = 0; idx != sizeof(INT8) / sizeof(int); ++idx)
                (*ip)[idx] = (idx + 1) * (idx + 1);

            return ip;
        }

In the above code fragment note the following:

- `squares` is declared inside of the `CppAnnotations::Virtual` namespace.
- `` The definition outside of the namespace region requires us to use the fully qualified name of the function and of its return type.
- `` Inside the body of the function `squares` we are within the `CppAnnotations::``Virtual` namespace, so inside the function fully qualified names (e.g., for `INT8`) are not required any more.

Finally, note that the function could also have been defined in the `CppAnnotations` region. In that case the `Virtual` namespace would have been required when defining `squares()` and when specifying its return type, while the internals of the function would remain the same:

        namespace CppAnnotations
        {
            namespace Virtual
            {
                void *pointer;

                using INT8 = int[8];

                INT8 *squares();
            }

            Virtual::INT8 *Virtual::squares()
            {
                INT8 *ip = new INT8[1];

                for (size_t idx = 0; idx != sizeof(INT8) / sizeof(int); ++idx)
                    (*ip)[idx] = (idx + 1) * (idx + 1);

                return ip;
            }
        }

## 4.2: The std::chrono namespace (handling time)

The C programming language offers tools like sleep(3) and select(2) to suspend program execution for a certain amount of time. And of course the family of time(3) functions for setting and displaying time

`Sleep` and `select` can be used for waiting, but as they were designed in an era when multi threading was unavailable, their usefulness is limited when used in multi threaded programs. Multi threading has become part of C++ (covered in detail in chapter 20), and additional time-related functions are available in the `std::filesystem` namespace, covered below in this chapter.

In multi threaded programs threads are frequently suspended, albeit usually for a very short time. E.g., when a thread wants to access a variable, but the variable is currently being updated by another thread, then the former thread should wait until the latter thread has completed the update. Updating a variable usually doesn't take much time, but if it takes an unexpectedly long time, then the former thread may want to be informed about that, so it can do something else while the latter thread is busy updating the variable. Interactions between threads like these cannot be realized with functions like `sleep` and `select`.

The `std::chrono` namespace bridges the gap between the traditionally available time-related functions and the time-related requirements of multi-threading and of the `std::filesystem` name space. All but the specific `std::filesystem` related time functionality is available after including the `<chrono>` header file. After including the `<filesystem>` header file the facilities of the `std::filesystem` are available.

Time can be measured in various resolutions: in Olympic Games time differences of hundreds of seconds may make the distinction between gold and silver medals, but when planning a vacation we might talk about it months before we go on vacation. Time resolutions are specified by objects of the class `std::ratio`, which (apart from including the `<chrono>` header file) is also available after including the `<ratio>` header file.

Different events usually last for different amounts of time (given a specific time resolution). Amounts of time are specified by objects of the class `std::chrono::duration`.

Events can also be characterized by their points in time: midnight, January 1, 1970 GMT is a point in time, as is 19:00, December 5, 2010. Points in time are specified by objects of the class `std::chrono::time_point`.

It's not just that resolutions, durations of events, and points in time of events may differ, but the devices (clocks) we use for specifying time also differ. In the past hour glasses were used (and sometimes they're still used when boiling eggs), but on the other hand we may use atomic clocks when measurements should be very precise. Four different types of clocks are available. The commonly used clock is `std::chrono::system_clock`, but in the context of the file system there's also a `std::chrono::file_clock`.

In the upcoming sections the details of the `std::chrono` namespace are covered. First we look at characteristics of time resolutions. How to handle amounts of time given their resolutions is covered next. The next section describes facilities for defining and handling time-points. The relationships between these types and the various clock-types are covered thereafter.

In this chapter the specification `std::chrono::` is often omitted (in practice `using namespace std` followed by `using namespace chrono` is commonly used; `[std::]chrono::` specifications are occasionally used to avoid ambiguities). Also, every now and then you'll encounter forward references to later chapters, like the reference to the chapter about multi-threading. These are hard to avoid, but studying those chapters at this point can safely be postponed without loss of continuity.

### 4.2.1: Time resolutions: std::ratio

Time resolutions (or units of time) are essential components of time specifications. Time resolutions are defined by objects of the class `std::ratio`.

Before the class `ratio` can be used, the `<ratio>` header file must be included. But the frquently included `<chrono>` header file already includes the `ratio` header file.

The class `ratio` has two template arguments. These are positive integral numbers surrounded by pointed brackets defining, respectively, the numerator and denominator of a fraction (by default the denominator equals 1). Examples:

        ratio<1>        - representing one;
        ratio<60>       - representing 60
        ratio<1, 1000>  - representing 1/1000.

The class `ratio` defines two directly accessible static data members: `num` represents its numerator, `den` its denominator. A `ratio` definition by itself simply defines a certain amount. E.g., when executing the following program

        #include <ratio>
        #include <iostream>
        using namespace std;

        int main()
        {
            cout << ratio<5, 1000>::num << ',' << ratio<5, 1000>::den << '\n';
        }

1,200 is displayed, as that's the `amount' represented by `ratio<5, 1000>`: `ratio` simplifies its fraction whenever possible.

Several predefined `ratio` types exist. They are, like `ratio` itself, defined in the standard namespace and can be used instead of the more cumbersome `ratio<x>` or `ratio<x, y>` specifications:

`yocto`

10-24

`zepto`

10-21

`atto` | 10-18 |  | `femto` | 10-15 |  | `pico` | 10-12
`nano` | 10-9 |  | `micro` | 10-6 |  | `milli` | 10-3
`centi` | 10-2 |  | `deci` | 10-1

`deca` | 101 |  | `hecto` | 102 |  | `kilo` | 103
`mega` | 106 |  | `giga` | 109 |  | `tera` | 1012
`peta` | 1015 |  | `exa` | 1018

`zetta` | 1021 |  | `yotta` | 1024

(note: the definitions of the types `yocto, zepto, zetta` and `yotta` use integral constants exceeding 64 bits. Although these constants are defined in C++, they are not available on 64 bit or smaller architectures.)

Time related ratios can very well be interpreted as fractions or multiple of seconds, with `ratio<1, 1>` representing a resolution of one second.

Here is an example showing how these abbreviations can be used:

            cout << milli::num << ',' << milli::den << '\n' <<
                    kilo::num << ',' << kilo::den << '\n';

### 4.2.2: Amounts of time: std::chrono::duration

Amounts of time are specified by objects of the class `std::chrono::duration`.

Before using the class `duration` the `<chrono>` header file must be included.

The class `duration` has two template arguments. A numeric type (`int64_t` is normally used) defining the type holding the duration's amount of time, and a time-resolution `ratio` (called its resolution).

Often the following predefined `duration` types are used:

`predefined:` |  | `duration type`

`nanoseconds` |  | `duration<int64_t, nano>`
`microseconds` |  | `duration<int64_t, micro>`
`milliseconds` |  | `duration<int64_t, milli>`
`seconds` |  | `duration<int64_t>`
`minutes` |  | `duration<int64_t, ratio<60>>`
`hours` |  | `duration<int64_t, ratio<3600>>`

E.g., to define a duration of 30 minutes use `minutes halfHour{ 30 }`.

The suffixes `h, min, s, ms, us, ns` are available for integral values, creating the corresponding `duration` times. E.g., `minutes min = 1h` stores 60 minutes in `min`.

Sub-types:

- `rep`: the duration's numeric type (commonly `int64_t`);
- `period`: the `ratio` type (like `kilo`). E.g., `minutes::period::num` equals 60.

Constructors:

- `duration()`:
  the default constructor initializes the object to 0 units;
- `duration(Type const &value)`:
  the object is initialized to `value` time units (`Type` refers to the duration's numeric type. E.g., when defining `minutes halfHour{ 30 }` the argument 30 is stored inside its `int64_t` data member).

Copy- and move-constructors (cf. chapter 9) are available.

Operators:

Duration types support assignment, negation (e.g., `halfHour = -halfHour`), addition and subtraction of duration values, and also multiplication, division and modulo computations by numeric factors. Compound assignment operators are also available. E.g.,

        minutes time = 2 * halfHour;    // time: 60 minutes
        time += minutes{ 30 };          // time: 90 minutes

Members:

- `Type count() const` returns the value stored inside the `duration` object. E.g., `minutes{ 30 }.count()` returns 30. The following members are static members;

- `duration::zero()` returns an (immutable) duration object whose `count` member returns 0. E.g., `seconds::zero().count()` returns `0s`;

- `duration::min()` returns an (immutable) duration object whose `count` member returns the lowest value of its `rep` type (i.e., `std::numeric_limits<duration::rep>::min()` (cf. section 21.11));

- `duration::max()` returns an (immutable) duration object whose `count` member returns the maximum value of its `rep` type.

Conversions:

The precision of left-hand side arguments of assignment operators must be greater than or equal to the precision of the right-hand side arguments (the left-hand argument may not lose precision). When using binary arithmetic operators the resulting duration type has a precision equal to the finer of the two precisions. E.g.,

        cout << (1min + 1h).count() << '\n';  // shows: 61
        hours hr{ 1 };
        halfHour += hr;                 // OK
        // hr += halfHours;             // won't compile

Durations can be converted by the `std::chrono::duration_cast<destination>(source)` function template, where `destination` is the destination's `duration` type and `source` is an available `destination` object, but `duration_cast` truncates the destination value when `destination's` precision is less than `source's` precision. E.g., `duration_cast<minutes>(seconds{ 90 })` returns `minutes{ 1 }`.

When the left-hand side argument's precision is less than the right-hand side's precision some decision must be made about how to handle the loss of precision. The following function template can be used to convert a duration to a less precise type, returning a `double` value, which can be, e.g., truncated or rounded.

        template <typename To, typename From>
        double durationCast(From from)
        {
            return static_cast<double>(from.count()) *
                                To::period::den * From::period::num /
                                (To::period::num * From::period::den);
        }

returning a `double` value (1.5 when called as `durationCast<minutes>(seconds{ 90 })`), leaving the decision how to use the returned `double` value to the caller.

### 4.2.3: Clocks measuring time

Clocks are used to measure time. C++ has several predefined clock types, defined in the `std::chrono` namespace.

Before using the `chrono` clocks the `<chrono>` header file must be included.

``Clock`' clock-types are used to define points in time and define the following sub-types:

- `Clock::duration`: the clock's time granularity type (by default using `nanoseconds`. E.g., `system_clock::duration oneDay{ 24h }`;

- `Clock::period`: the clock's `std::ratio` type. E.g., `system_clock::period::den`;

- `Clock::rep`: the type storing amounts of time. By default using `int64_t`). E.g., `system_clock::rep amount`;

- `Clock::time_point`: the type storing time points (covered in the next section). By default using `time_point<system_clock, nanoseconds>` E.g., `system_clock::time_point start`.

All clocks have a member `now` returning the clock type's `time_point` corresponding to the current time (relative to the clock's epoch). It is a static member which can be used like this: `system_clock::time_point tp = system_clock::now()`.

Four clock types are defined in the chrono namespace:

- `system_clock` is the `wall clock', using the system's real time clock;
- `steady_clock` is a clock whose time increases in parallel with the increase of real time;
- `high_resolution_clock` is the computer's fastest clock (i.e., the clock having the shortest timer-tick interval). In practice this is the same clock as `system_clock`.
- `file_clock`: used for time specifications of file-system elements. `File_clock` time specifications use a different starting (epoch) time than the other clocks, but it's easy to convert `file_clock` times to/from other clock types.

In addition to the member `now` the classes `system_clock` and `high_resolution_clock` (referred to as `Clock` below) provide two static members:

- `std::time_t Clock::to_time_t(Clock::time_point const &tp)`
  a `std::time_t` value (the same type as returned by C's time(2) function) converting a `time_point` value to a `time_t` value;

- `Clock::time_point Clock::from_time_t(std::time_tvseconds)`
  the opposite conversion: returning a `time_point` corresponding to a `time_t` value.

For example:

        system_clock::time_point now = system_clock::now();
        time_t value = system_clock::to_time_t(now);
        system_clock::time_point now2 = system_clock::from_time_t(value);

        // now2 != now since time_t uses seconds, not nanoseconds

### 4.2.4: Points in time: std::chrono::time_point

Points in time are specified by objects of the class `std::chrono::time_point`.

Before using the class `time_point` the `<chrono>` header file must be included.

Like `duration` the class `time_point` requires two template arguments: A clock type and a duration type. The standard clock types define their own `time_point` types using `nanoseconds` as their duration type (`time_point` by default uses `nanoseconds`). The following time point type definitions are therefore identical:

        time_point<standard_clock, nanoseconds>
        time_point<standard_clock>
        standard_clock::time_point

Constructors:

- `time_point()`:
  the default constructor is initialized to the beginning of the clock's epoch. For `system_clock` it is January, 1, 1970, 00:00h, but note that `file_clock::time_point` has a different starting point (see the example at the end of this section);

Copy- and move-constructors as well as copy- and move-assignment operators (cf. chapter 9) are available

Operators:

- `time_point &operator+=(duration const &amount)` adds the amount of time represented by `amount` to the current `time_point` object;

- `time_point &operator-=(duration const &amount)` subtracts the amount of time represented by `amount` from the current `time_point` object;

- `Type operator<<(std::ostream &, time_point const &)` inserts a textual representation of the `time_point's` UTC time into the `ostream`.

The compound operators are also available as binary arithmetic operators using a `time_point const &` and a `duration const &` operand (in any order). Example:

        system_clock::now() + seconds{ 5 };

Members:

- `duration time_since_epoch() const`:
  `duration` is the duration type used by the time point object for which this member is called. To convert the returned `duration` to a `size_t` value use `time_since_epoch().count()`;

- `time_point min() const`: a static member returning the time point's `duration::min` value. Example:

          cout <<
              time_point<system_clock>::min().time_since_epoch().count() << '\n';
              // shows -9223372036854775808

- `time_point max() const`: a static member returning the time point's `duration::max` value.

Conversions:

All predefined clocks use nanoseconds for their duration types. Converting to different `duration` types is covered in the previous section (4.2.2). Alternatively, the members `to_time_t` of the `system_clock` and the `high_resolution_clock` can be used to convert their `time_point` values to `time_t`. Such `time_t` values are commonly used to convert time to text, e.g., using the manipulator `put_time` (cf. section 6.3.2). The `put_time` manipulator must be provided with the address of a `std::tm` object, which can be obtained from a `std::time_t` value. See figure 3 for a visual representation of the involved elements.

Figure 3: Time according to C++

Use the following blueprint to insert a `system_clock::time point` value into a `std::ostream` (cf. section 6.4.4):

        int main()
        {
            auto now = system_clock::now();         // get a time_point
            cout << now << '\n';                    // now's UTC time
                                                    // convert to a time_t
            time_t timeT = system_clock::to_time_t(now);
            tm *local = localtime(&timeT);          // get a tm *
            cout << put_time(local, "%c") << '\n';  // show the time
        }

To convert a `time_point` to another `std::chrono` clock's `time_point` the template `DestClock::time_point std::chrono::clock_cast<DestClock>(TimePoint tp)` can be used. The argument `tp` is an available `time_point`, and `DestClock` specifies the clock type of the returned `time_point`. E.g., the following `cout` statement displays four identical times:

        auto fNow = file_clock::now();
        auto sNow = file_clock::to_sys(fnow);

        cout << fNow << '\n' <<
            sNow << '\n' <<
            clock_cast<system_clock>(fNow) << '\n' <<
            clock_cast<file_clock>(sNow) << '\n';

So, where is the starting point of the `file_clock` clock?
Since `time_point's` default cconstructor is initialized to its clock's starting point it can be obtained this way:

        cout << file_clock::time_point{}<< '\n';
        // shows:  2174-01-01 00:00:00.000000000

## 4.3: The std::filesystem namespace

Computers commonly store information that must survive reboots in their file systems. Traditionally, to manipulate the file system the C programming language offers functions performing the required system calls. Such functions (like rename(2), `truncate`(2), opendir(2), and realpath(3)) are of course also available in C++, but their signatures and way of use are often less attractive as they usually expect `char const *` parameters and may use static buffers or memory allocation based on malloc(3) and free(3).

Since 2003 the Boost library offers wrappers around these functions, offering interfaces to those system calls that are more C++-like.

Currently C++ directly supports these functions in the `std::filesystem` namespace. These facilities can be used after including the `<filesystem>` header file.

The `filesystem` namespace is extensive: it contains more than 10 different classes, and more than 30 free functions. To refer to the identifiers defined in the `std::filesystem` namespace their fully qualified names (e.g., `std::filesystem::path`) can be used. Alternatively, after specifying ``using namespace std::filesystem;`' the identifiers can be used without further qualifications. Namespace specifications like ``namespace fs = std::filesystem;`' are also encountered, allowing specifications like `fs::path`.

Functions in the `filesystem` namespace may fail. When functions cannot perform their assigned tasks they may throw exceptions (cf. chapter 10) or they may assign values to `error_code` objects that are passed as arguments to those functions (see section 4.3.1 below).

### 4.3.1: The class 'error_code'

Objects of the class `std::error_code` (note: not `std::filesystem::error_code`!) encapsulate error values, and associated error categories (cf. section 10.9; `error_code` can be used after including the `<system_error>` header, but it is also available after including the `<filesystem>` header file). Traditionally error values are available as values assigned to the global `int errno` variable. By convention, when `errno's` value equals zero there's no error. This convention was adopted by `error_code`.

Error codes can be defined for many conceptually different situations. Those situations are characterized by their own error categories.

Error categories are used to associate `error_code` objects with the errors that are defined by those categories. Default available error categories may use values like `EADDRINUSE` (or the equivalent `enum class errc` value `address_in_use`) but new types of error categories, tailored to other contexts, can also be defined. The `enum class errc` is defined in the `<bits/error_constants.h>` header file. Error categories and how to define them is covered near the end of the C++ Annotations (section 23.7.1).

Constructors:

- `error_code() noexcept`:
  the object is initialized with error value 0 and the `system_category` error category. Value 0 is not considered an error;

- `error_code(int ec, error_category const &cat) noexcept`:
  the object is initialized from error value `ec` (e.g., `errno`, set by a failing function), and a const reference to the applicable error category (provided by, e.g., `std::system_category()` or `std::generic_category()`). Here is an example defining an `error_code` object:

          error_code ec{ 5, system_category() };

- `error_code(ErrorCodeEnum value) noexcept`:
  this is a member template (cf. section 22.1.3), using template header `template <class ErrorCodeEnum>`. It initializes the object with the return value of `make_error_code(value)` (see below). In section 23.7 defining `ErrorCodeEnums` is covered. Note: `ErrorCodeEnum` as such does not exist. It is a mere placeholder for existing `ErrorCodeEnum` enumerations;

Copy- and move-constructors are available.

Operators:

- Standard assignment operators and an assignment operator accepting an `ErrorCodeEnum` are available;

- `operator std::errc() const noexcept`:
  returns the object's `errc` error-code value. For `g++` these are defined in the `enum class errc` in the file `/usr/include/x86_64-linux-gnu/c++/14/bits/error_constants.h`;

- `explicit operator bool() const noexcept`:
  returns `true` if the object's error value is unequal 0 (i.e., it represents and error).

Members:

- `void assign(int val, error_category const &cat)`:
  assigns new values to the object's error value and category. E.g, `ec.assign(0, generic_category())`;

- `error_category const &category() const noexcept`:
  returns a reference to the object's error category;

- `void clear() noexcept`:
  sets the `error_code's` value to 0 and its error category to `system_category`;

- `error_condition default_error_condition() const noexcept`:
  returns the current category's default error condition initialized with the current object's error value and error category (see section 10.9.2 for details about the class `error_condition`);

- `string message() const`:
  the message that is associated with the current object's error value is returned (equivalent to `category().message(ec.value())`);

- `int value() const noexcept`:
  returns the object's error value.

Free functions:

- Two `error_code` objects can be compared for (in) equality and can be ordered (using `operator<`).

  Ordering `error_codes` associated with different error categories has no meaning. But when the error categories are identical then they are compared by their error code values (cf. this SG14 discussion summary);

- `error_code make_error_code(errc value) noexcept`:
  returns an `error_code` object initialized with `static_cast<int>(value)` and `generic_category()`. This function converts an `enum class errc` value to an `error_code`.

  Other error related enums may also be defined with which tailored `make_error_code` functions can be associated (cf. section 23.7;)

- `std::ostream &operator<<(std::ostream & os, error_code const &ec)`:
  executes

      return os << ec.category().name() << ':' << ec.value();

Many `filesystem` functions define an optional last `error_code &ec` parameter. Those functions have `noexcept` specifications. If those functions cannot complete their tasks, then `ec` is set to the appropriate error code, calling `ec.clear()` if no error was encountered. If no `ec` argument is provided then those functions throw a `filesystem_error` exception if they cannot complete their tasks.

### 4.3.2: Types and permissions of file system elements: file_status

File system entries (represented by `path` objects, cf. section 4.3.3 below), have attributes: permissions (e.g., the owner may modify an entry), and types (like files, directories, and soft-links). Those attributes are defined in the class `std::filesystem::file_status`.

Types:

Defined in the `(std::filesystem) enum class file_type`.

std::filesystem::file_type
Type | Meaning

`not_found (= -1)` | the file system entry was not found (not considered an error)
`none` | the file status has not yet been evaluated or an error occurred when evaluating the status
`regular` | a regular file
`directory` | a directory
`symlink` | a symbolic link
`block` | a block device
`character` | a character device
`fifo` | a named pipe
`socket` | a socket file
`unknown` | an unknown file type

Permissions:

Defined in the `(std::filesystem) enum class perms`.

The enumeration's symbols were defined to make their meanings more descriptive than the constants defined in the `<sys/stat.h>` header file, but their values are identical. The `enum class perms` supports all bitwise operators.

std::filesystem::perms
Symbol | Value | sys/stat.h | Meaning

`none` | `0000` | `-``-``-` | No permission bits were set
`owner_read` | `0400` | `S_IRUSR` | File owner has read permission
`owner_write` | `0200` | `S_IWUSR` | File owner has write permission
`owner_exec` | `0100` | `S_IXUSR` | File owner has execute/search permissions
`owner_all` | `0700` | `S_IRWXU` | File owner has read, write, and execute/search permissions
`group_read` | `0040` | `S_IRGRP` | The file's group has read permission
`group_write` | `0020` | `S_IWGRP` | The file's group has write permission
`group_exec` | `0010` | `S_IXGRP` | The file's group has execute/search permissions
`group_all` | `0070` | `S_IRWXG` | The file's group has read, write, and execute/search permissions
`others_read` | `0004` | `S_IROTH` | Other users have read permission
`others_write` | `0002` | `S_IWOTH` | Other users have write permission
`others_exec` | `0001` | `S_IXOTH` | Other users have execute/search permissions
`others_all` | `0007` | `S_IRWXO` | Other users have read, write, and execute/search permissions
`all` | `0777` | `-``-``-` | All users have read, write, and execute/search permissions
`set_uid` | `04000` | `S_ISUID` | Set user ID to file owner user ID on execution
`set_gid` | `02000` | `S_ISGID` | Set group ID to file's user group ID on execution
`sticky_bit` | `01000` | `S_ISVTX` | POSIX XSI specifies that when set on a directory only file owners may delete files even if the directory is writeable by others (used, e.g., with `/tmp`)
`mask` | `07777` | `-``-``-` | All valid permission bits.

Perm_options:

The `(std::file_system) enum class perm_options` specifies the way file system entries are modified

std::filesystem::perm_options
Value | Meaning

`replace` | current permisions are replaced new permissions
`remove` | the specified permissions are removed from the file system entry's current permissions
`nofollow` | when the current file system entry refers to a symbolic link the permissions of the symbolic link itself are updated

Constructors:

- `explicit file_status(file_type type = file_type::none, perms permissions = perms::unknown)`

Copy and move constructors and assignment operators are avaialble;

Members:

- `perms permissions() const` returns the permissions of the file system entry represented by the `file_status` object.
  Refer to section 4.3.3.2 for the function `permissions` changing the permissions of a file system entry;

- `file_type type() const` returns the type of the file system entry to which the `file_status` object refers;

- `void type(file_type type)` changes the type of the file system entry to which the `file_tatus` object refers.

#### 4.3.2.1: The status of file system entries

The `std::path` free functions `status` and `symlink_status` (cf. section 4.3.3.2) return the `file_status` of file system entries.

The following functions provide specific information about the status of file system entries:

- `bool status_known(file_status const &status)` returns `true` if `status` refers to a determined status (`status` itself may indicate that the entity referred to by `status` does not exist). One way of receiving `false` is by passing it a default status object: `status_known(file_status{})`;

- `bool is_WHATEVER(file_status status)`, replacing `WHATEVER` by the requested file type, returns `true` if `status` refers to an entry of the specified type.

These following `is_WHATEVER` functions are available:

is_WHATEVER(file_status)
Function | Meaning

`is_block_file` | 'entry' is a block device
`is_character_file` | 'entry' is a character device
`is_directory` | 'entry' is a directory
`is_empty` | 'entry' is an empty file or directory
`is_fifo` | 'entry' is a named pipe
`is_other` | 'entry' is not a directory, regular file or symlink
`is_regular_file` | 'entry' is a regular file
`is_socket` | 'entry' is a named socket
`is_symlink` | 'entry' is a symbolic link

Here is a small program showing how file statuses can be obtained and displayed (cf. sections 4.3.3 and (for the map) section 12.3.7):

        namespace
        {
            std::unordered_map<file_type, char const *> statusMap =
            {
                { file_type::not_found, "an unknown file" },
                { file_type::none,      "not yet or erroneously evaluated "
                                                                    "file type" },
                { file_type::regular,   "a regular file" },
                { file_type::directory, "a directory" },
                { file_type::symlink,   "a symbolic link" },
                { file_type::block,     "a block device" },
                { file_type::character, "a character device" },
                { file_type::fifo,      "a named pipe" },
                { file_type::socket,    "a socket file" },
                { file_type::unknown,   "an unknown file type" }
            };
        }

        int main()
        {
            cout << oct;

            string line;
            while (true)
            {
                cout << "enter the name of a file system entry: ";
                if (not getline(cin, line) or line.empty())
                    break;

                path entry{ line };

                error_code ec;
                file_status stat = status(entry, ec);

                if (not status_known(stat))
                {
                    cout << "status of " << entry << " is unknown. "
                                                    "Ec = " << ec << '\n';
                    continue;
                }

                cout << "status of " << entry << ": type = " <<
                         statusMap[stat.type()] <<
                         ", permissions: " <<
                            static_cast<size_t>(stat.permissions()) << '\n';
            }
        }

### 4.3.3: Names of file system entries: path

Objects of the class `filesysten::path` commonly contain names of file system entries.

Constructors:

- `path()`: the default constructor is initialized with an empty `path`;
- `path(InputIter begin, InputIter end)`:
  the characters from `begin` to `end` define the `path's` name.

Copy- and move constructors are available, also using argument types `std::string` and `char const *`.
A `path` object doesn't have to refer to an existing file system entry.
Arguments of `path` constructors may contain (all optional):

- a root-name, e.g., a disk-name (like `E:`) or device indicator (like `//nfs`);
- a root-directory, if it is the first character after the (optional) root-name;
- filename characters (not containing directory separators). In addition the `single dot filename' (`.`) indicates the current directory and the `double dot filename' (`..`) indicates the current directory's parent directory;
- directory separators (by default the forward slash). Multiple consecutive separators are automatically merged into one separator.

The constructors also define a last `format ftmp = auto_format` parameter, for which in practice almost never an argument has to be provided (for its details see cppreference.)

#### 4.3.3.1: Accessors, modifiers and operators

Operators:

- `path &operator/=(Type const &arg)`:
  the arguments that can be passed to constructors can also be passed to this member. The `arg` argument is separated from the path's current content by a directory separator (unless the path is initially empty as in `cout << path{}.append("entry")`). See also the members `append` and `concat`, below. The free operator `/` accepts two `path` (promotable) arguments, returning a `path` containing both paths separated by a directory separator (e.g., `lhs / rhs` returns the `path` object `lhs/rhs`);

- `path &operator+=(Type const &arg)`:
  similar to `/=`, but no directory separator is used when adding `arg` to the current `path`;

- comparison operators: `path` objects can be compared using the (operators implied by the) `==` and `<=>` operators. Path objects are compared by lexicographical comparing their ascii-character content;

- `ostream &operator<<(ostream &out, path const &path)` (stream insertion) inserts `path's` content, surrounded by double quotes, into `out`;

- `istream &operator>>(istream &in, path &path)` extracts `path's` content from `in`. The extracted path name may optionally be surrounded by double quotes. When inserting a previously extracted `path` object only one set of surrounding quotes are shown.

Accessors:

Accessors return specific `path` components. If a path doesn't contain the requested component then an empty `path` is returned.

- `char const *c_str()`: the path's content is returned as an NTBS;

- `path extension()` returns the dot-extension of the path's last component (including the dot);

- `path filename()` returns the last path-content of the current `path` object. See also the `stem()` accessor, below;

- `bool is_absolute()`: returns `true` if the `path` object contains an absolute path specification;

- `bool is_relative()`: returns `true` if the `path` object contains a relative path specification;

- `path parent_path()` returns the current path-content from which the last element has been removed. Note that if the `path` object contains a filename's path (like `"/usr/bin/zip"`) then `parent_path` removes `/zip` and returns `/usr/bin`, so not `zip's` parent directory, but its actual directory;

- `path relative_path()`: returns the path's content beyond the path's root-directory component of the `path` object. E.g., if the `path ulb{ "/usr/local/bin" }` is defined then `ulb.relative_path()` returns a path containing `"usr/local/bin"`;

- `path root_directory()`: returns the root-directory component of the `path` object;

- `path root_name()`: returns the root-name's component of the `path` object;

- `path root_path()`: returns the root-path component of the `path` object;

- `path stem()` returns the last path-content of the current `path` object from which the dot-extension hash been removed;

- `string()`: returns the path's content as a `std::string`.
  Similar accessors are available for the following string-types: `wstring, u8string, u16string, , u32string, generic_string, generic_wstring, generic_u8string, generic_u16string,` and `generic_u32string`;

Except for the family of `string()` and the `is_...` accessors, there are also `bool has_...` members returning `true` if the `path` contains the specified component (e.g., `has_extension` returns `true` if the `path` contains an extension).

Member functions:

- `path &append(Type const &arg)` acts like the `/=` operator;

- `path::iterator begin()` returns an iterator containing the first path component; Dereferencing a `path::iterator` returns a `path` object.
  When available root names and root directories are returned as initial components. When incrementing `path::iterators` the individual directories and finally filename components are returned. The directory separators themselves are not returned when dereferencing subsequent `path::iterators`;

- `path::const_iterator begin() const` returns a iterator to the immutable first path component; Dereferencing a `path::const_iterator` returns a `path const` object;

- `void clear()`: the `path's` content is erased;

- `int compare(Type const &other)`:
  returns the result of lexicographically comparing the current path's content with `other`. `Other` can be a `path`, a string-type or an NTBS;

- `path &concat(Type const &arg)` acts like the `+=` operator;

- `path::iterator end()` returns an iterator beyond the last path component;

- `path::const_iterator end() const` returns an iterator beyond the immutable last path component

- `path &remove_filename()`:
  removes the last component of the stored path not ending in `/`. If the `path` doesn't contain a slash then the `path` object's cleared;

- `path &replace_extension(path const &replacement = path{} )`:
  replaces the extension of the last component of the stored path (including the extension's dot) with `replacement`. The extension is removed if `replacement` is empty. If the `path` calling `replace_extension` has no extension then `replacement` is added. The replacement may optionally start with a dot. The path object's extension receives only one dot;

- `path &replace_filename(path const &replacement)`:
  replaces the last component of the stored path with `replacement`, which itself may contain multiple path elements. If only a root-directory is stored, then it is replaced by `replacement`. The member's behavior is undefined if the current path object is empty;

#### 4.3.3.2: Free functions

Copy_options:

Defined in the `(std::filesystem) enum class copy_options`.

The enumeration supports bitwise operators. The `copy_options` enum values are used to fine-tune the behavior of `filesystem` functions copying file system elements.

std::filesystem::copy_options
Symbol | Value |  | Meaning

`none` | `0` |  | default: copy like `cp`

`overwrite_existing` | `2` |  | replace the destination file
`update_existing` | `4` |  | replace the destination file only if it is older than the file being copied

`recursive` | `8` |  | recursively copy subdirectories and their content
`copy_symlinks` | `16` |  | copy symlinks as symlinks
`skip_symlinks` | `32` |  | ignore symlinks

`directories_only` | `64` |  | copy the directory structure, but do not copy any non-directory files
`create_symlinks` | `128` |  | create symlinks instead of copying files. The source path must be an absolute path unless the destination path is in the current directory
`create_hard_links` | `256` |  | instead of copying files create hard links resolving to the same files as the original

Functions:

- `path absolute(path const &src, [, error_code &ec])`:
  returns `src` as an absolute path (i.e., starting at the filesystem's root (and maybe disk) name). It can be called as, e.g., `absolute("tmp/filename")`, returning the (absolute) current working directory to which `absolute's` argument is appended as a final element, separated by a directory separator. Relative path indicators (like `../` and `./`) are kept;

- `path canonical(path const &src [, error_code &ec])`:
  returns `src's` canonical path. `Src` must exist. Example:

          canonical("/usr/local/bin/../../share/man");
           // returns path{ "/usr/share/man" }

- `void copy(path const &src, path const &dest [, copy_options opts [, error_code &ec]])`:
  `src` must exist. By default copies `src` to `dest` if the `cp` program would also succeed. Use `opts` to fine-tune `copy's` behavior.
  If `src` is a directory, and `dest` does not exist, `dest` is created. Directories are recursively copied if copy options `recursive` or `none` were specified;

- `bool copy_file(path const &src, path const &dest [, copy_options opts [, error_code &ec]])`:
  `src` must exist. Copies `src` to `dest` if the `cp` program would also succeed. Symbolic links are followed. The value `true` is returned if copying succeeded;

- `void copy_symlink(path const &src, path const &dest [, error_code &ec])`:
  creates the symlink `dest` as a copy of the symlink `src`;

- `bool create_directories(path const &dest [, error_code &ec])`:
  creates each component of `dest`, unless already existing. E.g., using argument `"a/b/c"` and `"a"` doesn't yet exist then `"a/b/c"` are all created. The value `true` is returned if `dest` was actually created. If `false` is returned `ec` contains an error-code, which is zero (`ec.value() == 0`) if `dest` already existed. See also `create_directory` below;

- `bool create_directory(path const &dest [, path const &existing] [, error_code &ec])`:
  `dest's` parent directory must exist. This function creates directory `dest` if it does not yet exist. Nested subdirectories are not created by `create_directory`: using argument `"a/b/c"` and neither `"a"` nor `"a/b"` exist then this function fails. The value `true` is returned if `dest` was actually created. If `false` is returned `ec` contains an error-code, which is zero (`ec.value() == 0`) if `dest` already existed. If `existing` is specified, then `dest` receives the same attributes as `existing`;

- `void create_directory_symlink(path const &dir, path const &link [, error_code &ec])`:
  like `create_symlink` (see below), but is used to create a symbolic link to a directory;

- `void create_hard_link(path const &dest, path const &link [, error_code &ec])`:
  creates a hard link from `link` to `dest`. `Dest` must exist;

- `void create_symlink(path const &dest, path const &link [, error_code &ec])`:
  creates a symbolic (soft) link from `link` to `dest`; `dest` does not have to exist;

- `path current_path([error_code &ec])`, `void current_path(path const &toPath [, error_code &ec])`:
  the former function returns the current working directory (cwd), the latter changes the cwd to `toPath`. The returned path's last character is not a slash, unless called from the root-directory;

- `bool equivalent(path const &path1, path const &path2 [, error_code &ec])`:
  `true` is returned if `path1` and `path2` refer to the same file or directory, and have identical statuses. Both paths must exist;

- `bool exists(path const &dest [, error_code &ec])`, `exists(file_status status)`:
  `true` is returned if `dest` exists (actually: if `status(dest[, ec])` (see below) returns `true`). Note: when iterating over directories, the iterator usually provides the entries' statuses. In those cases calling `exists(iterator->status())` is more efficient than calling `exists(*iterator)`. When `dest` is the path to a symbolic reference then `exists` returns whether the link's destination exists or not (see also the functions `status` and `symlink_status` in section 4.3.4);

- `std::unintmax_t file_size(path const &dest [, error_code &ec])`:
  returns the size in bytes of a regular file (or symlink destination);

- `std::uintmax_t hard_link_count(path const &dest [, error_code &ec])`:
  returns the number of hard links associated with `dest`;

- `file_clock::time_point last_write_time(path const &dest [, error_code &ec])`, `void last_write_time(path const &dest, file_clock::time_point newTime [, error_code &ec])`:
  the former function returns `dest's` last modification time; the latter function changes `dest's` last modification time to `newTime`. `last_write_time's` return type is defined through a `using` alias for `chrono::time_point` (cf. section 4.2.4). The returned `time_point` is guaranteed to cover all file time values that may be encountered in the current file system. The function `file_clock::to_sys` (see below) can be used to convert `file_clock` time points to `system_clock` time_points;

- `void permissions(Path const &entry, perms newPerms [, perm_options opts = perm_options::replace ] [, error_code &ec])`:
  Modifies the permissions of `entry`. Each of the two last arguments is optional. E.g., when specifying an `error_code` as third argument then `opts` is implicitly specified as `replace`;

- `path read_symlink(path const &src [, error_code &ec])`:
  `src` must refer to a symbolic link or an error is generated. The link's target is returned;

- `bool remove(path const &dest [, error_code &ec])`, `std::uintmax_t remove_all(path const &dest [, error_code &ec])`:
  `remove` removes the file, symlink, or empty directory `dest`, returning `true` if `dest` could be removed; `remove_all` removes `dest` if it's a file (or symlink); and recursively removes directory `dest`, returning the number of removed entries;

- `void rename(path const &src, path const &dest [, error_code &ec])`:
  renames `src` to `dest`, as if using the standard mv(1) command (if `dest` exists it is overwritten);

- `void resize_file(path const &src, std::uintmax_t size [, error_code &ec])`:
  `src's` size is changed to `size` as if using the standard truncate(1) command;

- `space_info space(path const &src [, error_code &ec])`:
  returns information about the file system in which `src` is located;

- `file_status status(path const &entry [, error_code &ec])`:
  returns `entry's file_status`. If `entry` is the name of a symbolic link then the status of the link's destination is returned;

- `file_status symlink_status(path const &entry [, error_code &ec])`:
  returns `entry's` own `file_status`;

- `path system_complete(path const &src[, error_code& ec])`:
  returns the absolute path matching `src`, using `current_path` as its base;

- `path temp_directory_path([error_code& ec])`:
  returns the path to a directory that can be used for temporary files. The directory is not created, but its name is commonly available from the environment variables `TMPDIR`, `TMP, TEMP`, or `TEMPDIR`. Otherwise, `/tmp` is returned.

- `system_clock::time_point file_clock::to_sys(file_clock::time_point timePoint)`:
  here is how the time returned by `last_write_time` can be represented using the `system_clock's` epoch:

      int main()
      {
          time_t seconds = system_clock::to_time_t(
                          file_clock::to_sys(last_write_time("lastwritetime.cc"))
                      );

          cout << "lastwritetime.cc's last (UTC) write time: " <<
                   put_time(gmtime(&seconds), "%c") << '\n';
      }

### 4.3.4: Handling directories: directory_entry

The file system is a recursive data structure. Its top-level entry is a directory (the root directory) containing plain directory entries (files, (soft) links, named sockets, etc.) and possibly also (sub)directory entries referring to nested directories which in turn may contiain plain- and (sub)directory entries.

In the `std::filesystem` namespace the elements of directories are objects of the class `directory_entry`, containing names and statuses of the entries of that directory.

Constructors:

The class `directory_entry` supports all standard constructors (and assignment operators) and also a constructor expecting a `path`:

        directory_entry(path const &entry);

Objects of the class `directory_entry` can be constructed by name, and do not have to refer to existing entries in the file system.

Operators:

- `ostream &operator<<(ostream &, directory_entry const &)` inserts the object's `path` into the `ostream`;

- the comparsion operators (`==, <=>`) compare their `std::path` data members;

- `path const &path() const`, `operator path const &() const` returns the current object's path name.

Members:

- `void assign(path const &dest)`:
  the current path is replaced by `dest` (identical to `directory_entry's` assignment operator);

- `void replace_filename(path const &dest)`:
  the last element of the current object's path is replaced by `dest`. If that element is empty (e.g., when the object's path ends in a directory separator) then `dest` is appended to the current object's path;

- `filesystem::file_status status([error_code &ec])`:
  returns type and attributes of the directory entry referred to by the current object. If the current object refers to a symlink then the status of the entry the symlink refers to is returned. To obtain the status of the entry itself, even if it's a symlink use `symlink_status` (see also section 4.3.2 and 4.3.2.1 below).

#### 4.3.4.1: Visiting directory entries: (recursive_)directory_iterator

The `filesystem` namespace has two classes simplifying directory processing: objects of the class `directory_iterator` are (input) iterators iterating over the entries of directories; and objects of the class `recursive_directory_iterator` are (input) iterators recursively visiting all entries of directories.location

enum class directory_options

The `enum class directory_options` defines values that are used to fine-tune the behavior of `recursive_directory_iterator` objects, supporting bitwise operators (the values of its symbols are shown between parentheses):

- `none` (0): directory symlinks are skipped, denied permission to enter a sub-directory generates an error;
- `follow_directory_symlink` (1): symlinks to sub-directories are followed;
- `skip_permission_denied` (2): directories that cannot be entered are silently skipped.

Constructors:

- `(recursive_)directory_iterator()`:
  the end-iterator of the `(recursive_)directory_iterator's` iterator-range;

- `(recursive_)directory_iterator(path const &from [, error_code &ec])`:
  constructs a `(recursive-)directory_iterator` using `from` as the starting directory of the iterator. All members of standard input iterators (cf. section 18.2) are supported;

- `recursive_directory_iterator(path const &from, directory_options opts [, error_code &ec])`:
  constructs a `(recursive-)directory_iterator` fine-tuning its behavior to the options specified by `opts`.

Copy, and move constructors are available.

These iterators point to `directory_entry` objects referring to entries in the computer's file system. E.g.,

        cout << *directory_iterator{ "/home" } << '\n';
                    // shows the first entry under /home

`(Recursive_)directory_iterators` can be used with range-based for-loops and in standard `for` and `while` statements.

Additional members of recursive_directory_iterators

- `int depth() const`:
  returns the current iteration depth. The depth of the initial directory, specified at construction-time, equals 0;

- `void disable_recursion_pending()`:
  when called before incrementing the iterator the next directory entry is not recursively visited. Once the iterator is incremented recursion is again allowed. If a recursion should end at a specific depth then once `depth()` returns that specific depth this member must be called each time before the iterator's increment operator is called;

- `recursive_directory_iterator &increment(error_code &ec)`:
  acts identically to the iterator's increment operator. However, at errors `operator++` throws a `filesystem_error` exception, while `increment` assigns the error to `ec`;

- `directory_options options() const`:
  returns the option(s) specified at construction-time;

- `void pop()`:
  ends processing the current directory, and continues at the next entry in the current directory's parent;

- `bool recursion_pending() const`:
  `true` is returned if recursive processing of sub-directories of the currently processed directory is allowed. If so, and the the iterator points at a sub-directory, then processing continues in that sub-directory at the iterator's next increment;

Here's a small program displaying all elements and all immediate sub-directories of a directory:

        int main()
        {
            recursive_directory_iterator base{ "/var/log",
                                          directory_options::skip_permission_denied };

            for (auto entry = base, endIt = end(base); entry != endIt; ++entry)
            {
                cout << entry.depth() << ": " << *entry << '\n';
                if (entry.depth() == 1)
                    entry.disable_recursion_pending();
            }
        }

The above program handles entries as they come. Other strategies must be implemented `by hand'. E.g., a breadth-first strategy first visits all the non-directory entries and then visits the sub-directories, as illustrated in the next example by processingthe directories stored in `level` in turn (initially it merely contains the starting directory).

`Processing a directory' means that its non-directory entries are directly processed storing the names of sub-directories in `next`. Once all entries at `level` have been processed the names of the next level sub-directories are available (in `next`). By assigning `next` to `level` all directories at the next level are processed. When reaching the most deeply nested sub-directories its `next` is empty and the `while` statement ends:

        void breadth(path const &dir)           // starting dir.
        {
            vector<path> level{ dir };          // currently processed level

            while (not level.empty())           // process all its dirs.
            {
                vector<path> next;              // dirs of the next level

                for (auto const &dir: level)    // visit all dirs at this level
                {
                    cout << "At " << dir << '\n';
                                                // at each dir: visit all entries
                    for (auto const &entry: directory_iterator{ dir })
                    {
                        if (entry.is_directory())   // store all dirs at the current
                            next.push_back(entry);  //  level
                        else                        // or process its non-dir entry
                            cout << "   entry: " << entry << '\n';
                    }
                }

                level = next;                   // continue at the next level,
            }                                   // which eventually won't exist
        }

### 4.3.5: Information about the space of file systems: space_info

Every existing `path` lives in a file system, Sizes of file systems typically are quite large, but there is a limit to their sizes.

The size of file systems, the number of bytes that is currently being used and the remaining number of bytes is made available by the function `space(path const &entry [, error_code &ec])`, returning the information about the file system containing `entry` in a POD `struct space_info`.

If the `error_code` argument is provided then it is cleared if no error occurs, and set to the operating system's error code if an error has occurred. If an error occurs and the `error_code` argument was not provided then a `filesystem_error` exception is thrown, receiving `path` as its first argument and the operating system's error code as its `error_code` argument.

The returned `space_info` has three fields:

        uintmax_t capacity;     // total size in bytes
        uintmax_t free;         // number of free bytes on the file system
        uintmax_t available;    // free bytes for a non-privileged process

If a field cannot be determined it is set to -1 (i.e., the max. value of the type `uintmax_t`).

The function can be used this way:

        int main()
        {
            path tmp{ "/tmp" };

            auto pod = space(tmp);

            cout << "The filesystem containing /tmp has a capacity of " <<
                                                    pod.capacity << " bytes,\n"
                "i.e., " << pod.capacity / (1024 * 1024) << " MB.\n"
                "# free bytes: " << pod.free << "\n"
                "# available:  " << pod.available << "\n"
                "free + available:  " << pod.free + pod.available << '\n';
        }

### 4.3.6: File system exceptions: filesystem_error

The `std::filesystem` namespace offers its own exception type `filesystem_error` (see also chapter 10). Its constructor has the following signature (the bracketed parameters are optional):

        filesystem_error(string const &what,
                        [path const &path1, [path const &path2,]]
                        error_code ec);

As `filesystem` facilities are closely related to standard system functions, `errc` error code enumeration values can be used to obtain `error_codes` to pass to `filesystem_error`, as illustrated by the following program:

        int main()
        try
        {
            try
            {
                throw filesystem_error{ "exception encountered", "p1", "p2",
                                            make_error_code(errc::address_in_use) };
            }
            catch (filesystem_error const &fse)
            {
                cerr << "what:  " << fse.what() << "\n"
                        "path1: " << fse.path1() << "\n"
                        "path2: " << fse.path2() << "\n"
                        "code:  " << fse.code() << '\n';

                throw;
            }
        }
        catch (exception const &ec)
        {
            cerr << "\n"
                    "plain exception's what: " << ec.what() << "\n\n";
        }

- Table of Contents
- Previous Chapter
- Next Chapter