Namespaces

   The code inside a namespace should be in the same nesting level as the namespace.

Example

#include <iostream>
#include <cstdint>
#include <utility>
#include <string>
#include <memory>

namespace person
{

template<typename T>
using Name = std::unique_ptr<T>;
template<typename T>
using Age = std::unique_ptr<T>;

template<typename T1, typename T2>
class Person
{
  private:
  // Private Members
    Name<T1> name;
    Age<T2> age;
  public:
  // Constructors
    template<typename U1, typename U2>
    Person(U1&& name, U2&& age);
  // Public Methods
    // Element Access
    T1 const& get_name();
    T2 const& get_age();
  // Operators
    template<typename _T1, typename _T2>
    friend std::ostream& operator<<(std::ostream& os, Person<_T1,_T2> const& p);
};

//
// Constructors
//

template<typename T1, typename T2>
template<typename U1, typename U2>
Person<T1,T2>::Person(U1&& name, U2&& age)
  : name(std::make_unique<
      typename Name<T1>::element_type>(std::forward<U1>(name)))
  , age(std::make_unique<
      typename Age<T2>::element_type>(std::forward<U2>(age)))
{
}

//
// Public Methods
//

template<typename T1, typename T2>
T1 const& Person<T1,T2>::get_name()
{
  return *(this->name);
}

template<typename T1, typename T2>
T2 const& Person<T1,T2>::get_age()
{
  return *(this->age);
}

//
// Operators
//

template<typename _T1, typename _T2>
std::ostream& operator<<(std::ostream& os, Person<_T1,_T2> const& p)
{
  std::cout << "Name: " << *(p.name) << std::endl;
  std::cout << "Age: " << *(p.age);
  return os;
}
} // namespace person

int main(int argc, char const* argv[])
{
  using Person = person::Person<std::string, int16_t>;

  std::string name_augustine = "augustine";
  Person augustine{name_augustine, 33};

  Person mary{"mary", 42};

  std::cout << mary << std::endl;
  std::cout << augustine << std::endl;

  return 0;
}

Structuring your namespaces

   All the namespaces names should be in the singular form.

Consider the following project structure:

- anastasia
| - include
| | - CMakeLists.txt
| | - anastasia
| | | - component-a.hpp
| | | - component-a
| | | | - algorithm.hpp
| | | | - enumeration.hpp
| | | - component-b.hpp
| | | - component-b
| | | | - binary-tree.hpp
| | | | - data-structure.hpp
| - extern
| - doc
| - test
| - CMakeLists.txt

The approach taken to minimize name collision, is to follow the directory structure of your project.

   Now, how does that work?

The top level file

Lets consider the file component-a.hpp, it is in the top level of the anastasia project source files. Therefore, it should use the namespace equivalent to its name in the snake_case format.

Example

The example below illustrates the contents of the component-a.hpp file.

namespace component_a
{
// Functionalities
} // namespace component_a

   Reiterating, the namespace is the source filename converted, to the snake_case format

   Does the namespace name has to be grammatically equivalent to the class name?

That is true for the top level source file. This simplifies the access to a functionality, given a namespace, you know how to access it in a more natural way.

   What about the components/functionalities of your class?

This will the discussed below.

The components/functionalities

Now lets consider one of the source files of the component-a folder.

   The component-a folder represents the implementations of component-a.hpp functionalities/components.

The methodology for naming the namespace is the same as of the top level source file, i.e., use the filename. Only this time, you are representing a functionality/component of your top level source file, so it should be nested within the namespace of the top level source file.

Example

Give the component-a/algorithm.hpp file, the namespace should be structured as follows:

namespace component_a::algorithm
{
} // namespace component_a::algorithm

   Notice that, in both examples, the namespace ends with a comment that uses the namespace keyword, and follows by repeating the namespace identifier. This is a good practice to avoid accidentally erasing the namespace closing bracket.