Write a library in C++ to generate passwords. The library consists of one file (.cpp). The library allows you to generate passwords in String format with the following parameters:
- Password length;
- Symbols used: lowercase, uppercase letters, numbers, special characters;
- Number of generated passwords.
The library also makes it possible to check the strength of a password using a simple formula. When writing a library, use the Abstract Factory and Command patterns. In the main() function, give a brief example of using the library. Avoid mistakes in C++ code. Do not use third-party libraries and frameworks. All anomalous situations, errors and invalid data entered must be handled using a try catch block and throw function. In your answer, write as much C++ code as possible and less explanation with text.

Reference information on programming patterns that may help you:

The Abstract Factory pattern provides an interface for creating families of related or dependent objects without specifying their concrete classes. That is, this pattern is used to create a set of objects that must work together. This approach allows code to work with objects without being tied to specific object classes.

Components of the “Abstract Factory” pattern:
1. Abstract Factory - declares an interface for creating abstract product objects.
2. Concrete Factory - implements the operations of creating concrete products.
3. Abstract Product - declares an interface for the product type of objects.
4. Concrete Product - a specific implementation of products that are created by the corresponding factories.
5. Client - uses only interfaces declared by the Abstract Factory and Abstract Product classes.

Example in C++:

#include <iostream>
#include <memory>

// Abstract classes of products that will be created
class AbstractProductA {
public:
     virtual ~AbstractProductA() {}
     virtual std::string UsefulFunctionA() const = 0;
};

class AbstractProductB {
public:
     virtual ~AbstractProductB() {}
     virtual std::string UsefulFunctionB() const = 0;
     virtual std::string AnotherUsefulFunctionB(const AbstractProductA &collaborator) const = 0;
};

// Concrete product classes derived from abstract ones
class ConcreteProductA1 : public AbstractProductA {
public:
     std::string UsefulFunctionA() const override {
         return "ProductA1";
     }
};

class ConcreteProductB1 : public AbstractProductB {
public:
     std::string UsefulFunctionB() const override {
         return "ProductB1";
     }

     std::string AnotherUsefulFunctionB(const AbstractProductA &collaborator) const override {
         return "ProductB1 collaborates with " + collaborator.UsefulFunctionA();
     }
};


class ConcreteProductA2 : public AbstractProductA {
public:
     std::string UsefulFunctionA() const override {
         return "ProductA2";
     }
};

class ConcreteProductB2 : public AbstractProductB {
public:
     std::string UsefulFunctionB() const override {
         return "ProductB2";
     }

     std::string AnotherUsefulFunctionB(const AbstractProductA &collaborator) const override {
         return "ProductB2 collaborates with " + collaborator.UsefulFunctionA();
     }
};

// Abstract factory for creating product families
class AbstractFactory {
public:
     virtual ~AbstractFactory() {}
     virtual std::unique_ptr<AbstractProductA> CreateProductA() const = 0;
     virtual std::unique_ptr<AbstractProductB> CreateProductB() const = 0;
};

// Specific factories for creating product families
class ConcreteFactory1 : public AbstractFactory {
public:
     std::unique_ptr<AbstractProductA> CreateProductA() const override {
         return std::make_unique<ConcreteProductA1>();
     }

     std::unique_ptr<AbstractProductB> CreateProductB() const override {
         return std::make_unique<ConcreteProductB1>();
     }
};

class ConcreteFactory2 : public AbstractFactory {
public:
     std::unique_ptr<AbstractProductA> CreateProductA() const override {
         return std::make_unique<ConcreteProductA2>();
     }

     std::unique_ptr<AbstractProductB> CreateProductB() const override {
         return std::make_unique<ConcreteProductB2>();
     }
};

// Client code
void ClientCode(const AbstractFactory &factory) {
     auto productA = factory.CreateProductA();
     auto productB = factory.CreateProductB();
     std::cout << productB->UsefulFunctionB() << std::endl;
     std::cout << productB->AnotherUsefulFunctionB(*productA) << std::endl;
}

int main() {
     std::cout << “Client: Testing client code with the first factory type:” << std::endl;
     ConcreteFactory1 factory1;
     ClientCode(factory1);
    
     std::cout << std::endl;
    
     std::cout << “Client: Testing client code with the second factory type:” << std::endl;
     ConcreteFactory2 factory2;
     ClientCode(factory2);
    
     return 0;
}

In this example, ConcreteFactory1 and ConcreteFactory2 are two factories that create two different product families: ProductA1 with ProductB1 and ProductA2 with ProductB2 respectively. ClientCode works with abstract factories and products and is not aware of concrete classes.

Thus, the Abstract Factory pattern allows you to introduce new product variations (for example, new product families) without changing existing client code, which makes it easier to extend the program.

The Command pattern transforms queries into objects, allowing you to parameterize objects with other queries, queue or log queries, and support cancellation of operations. This pattern is typically used to separate the class that performs the operation from the class that sends the request for execution.

The pattern consists of the following components:
- Command: An interface that declares a method to execute a command.
- ConcreteCommand: A concrete class that implements the Command interface that controls an operation performed by one or more receivers.
- Client: a class that creates a Command object and sets its recipient.
- Invoker: a class that is associated with one or more commands. It sends a command request to perform the corresponding operations.
- Receiver: a class that knows how to perform the operations required to complete a request. Some action is performed by the Receiver in response to a Command request.

An example of the implementation of the Command pattern in C++:

#include <iostream>
#include <vector>
#include <memory>

//Command
class Command {
public:
     virtual ~Command() = default;
     virtual void execute() = 0;
};

// Receiver
class Light {
public:
     void turnOn() {
         std::cout << “The light is on.” << std::endl;
     }

     void turnOff() {
         std::cout << “The light is off.” << std::endl;
     }
};

// ConcreteCommand
class TurnOnCommand : public Command {
private:
     Light&light;

public:
     explicit TurnOnCommand(Light& l) : light(l) {}
     void execute() override {
         light.turnOn();
     }
};

class TurnOffCommand : public Command {
private:
     Light&light;

public:
     explicit TurnOffCommand(Light& l) : light(l) {}
     void execute() override {
         light.turnOff();
     }
};

// Invoker
class RemoteControl {
private:
     std::vector<std::unique_ptr<Command>> commands;

public:
     void submit(std::unique_ptr<Command> command) {
         commands.push_back(std::move(command));
     }

     void pressButtons() {
         for (auto& command : commands) {
             command->execute();
         }
         commands.clear();
     }
};

// Client
int main() {
     Light light;

     RemoteControl remote;
     remote.submit(std::make_unique<TurnOnCommand>(light));
     remote.submit(std::make_unique<TurnOffCommand>(light));

     remote.pressButtons();
     return 0;
}

In this example, Light is the Receiver, and TurnOnCommand and TurnOffCommand are ConcreteCommands that perform operations on Light. RemoteControl serves as an Invoker that accepts commands and executes them. The main() function plays the role of the Client, creating commands and configuring the Invoker.

When you call the pressButtons method on a RemoteControl object, each command in the commands queue will be executed, causing the Light state to change according to the commands.