#include <iostream>
#include <string>
#include <vector>

// ============================================================
// Namespace declaration for a math library
// ============================================================
namespace MathUtils {
    // Constants
    const double PI = 3.14159265359;
    const double E = 2.71828182846;

    // Functions
    int add(int a, int b) {
        return a + b;
    }

    double add(double a, double b) {
        return a + b;
    }

    int square(int x) {
        return x * x;
    }

    double square(double x) {
        return x * x;
    }

    // Nested namespace
    namespace Advanced {
        double power(double base, int exp) {
            double result = 1.0;
            for (int i = 0; i < exp; ++i) {
                result *= base;
            }
            return result;
        }
    }
}

// ============================================================
// Namespace declaration for a string utilities library
// ============================================================
namespace StringUtils {
    std::string toUpperCase(const std::string& str) {
        std::string result = str;
        for (char& c : result) {
            c = std::toupper(c);
        }
        return result;
    }

    std::string toLowerCase(const std::string& str) {
        std::string result = str;
        for (char& c : result) {
            c = std::tolower(c);
        }
        return result;
    }

    bool contains(const std::string& str, char ch) {
        return str.find(ch) != std::string::npos;
    }
}

// ============================================================
// Another namespace with the same name (can be extended)
// ============================================================
namespace StringUtils {
    // Additional function added to the same namespace
    int countWords(const std::string& str) {
        int count = 0;
        bool inWord = false;
        for (char c : str) {
            if (std::isalpha(c) && !inWord) {
                inWord = true;
                ++count;
            } else if (!std::isalpha(c)) {
                inWord = false;
            }
        }
        return count;
    }
}

// ============================================================
// Inline namespace for versioning (C++11)
// ============================================================
namespace V1 {
    void printVersion() {
        std::cout << "Version 1.0" << std::endl;
    }
}

namespace V2 {
    inline namespace Latest {
        void printVersion() {
            std::cout << "Version 2.0 (Latest)" << std::endl;
        }
        void newFeature() {
            std::cout << "New feature in version 2.0" << std::endl;
        }
    }
}

// ============================================================
// Anonymous namespace (file-local scope)
// ============================================================
namespace {
    int internalCounter = 0;

    void incrementCounter() {
        ++internalCounter;
    }

    int getCounter() {
        return internalCounter;
    }
}

// ============================================================
// Namespace with a class
// ============================================================
namespace Container {
    class MyVector {
    private:
        std::vector<int> data;
    public:
        void push(int value) {
            data.push_back(value);
        }

        void display() {
            std::cout << "Vector contents: ";
            for (int val : data) {
                std::cout << val << " ";
            }
            std::cout << std::endl;
        }

        size_t size() const {
            return data.size();
        }
    };
}

// ============================================================
// Namespace alias
// ============================================================
namespace MathAdv = MathUtils::Advanced;

// ============================================================
// Using directive (not recommended in headers, but OK in .cpp)
// ============================================================
using namespace std;

int main() {
    // ---------------------------------------------------------
    // 1. Qualified name access (fully qualified)
    // ---------------------------------------------------------
    cout << "=== Qualified Name Access ===" << endl;
    cout << "PI = " << MathUtils::PI << endl;
    cout << "add(5, 3) = " << MathUtils::add(5, 3) << endl;
    cout << "square(4.5) = " << MathUtils::square(4.5) << endl;
    cout << endl;

    // ---------------------------------------------------------
    // 2. Using declaration (bring specific names into scope)
    // ---------------------------------------------------------
    cout << "=== Using Declaration ===" << endl;
    using MathUtils::add;
    using MathUtils::square;

    // Now we can use add and square without qualification
    cout << "add(10, 20) = " << add(10, 20) << endl;
    cout << "square(7) = " << square(7) << endl;
    // But PI still needs qualification
    cout << "PI = " << MathUtils::PI << endl;
    cout << endl;

    // ---------------------------------------------------------
    // 3. Using directive (bring entire namespace)
    // ---------------------------------------------------------
    cout << "=== Using Directive ===" << endl;
    using namespace StringUtils;

    string text = "Hello World!";
    cout << "Original: " << text << endl;
    cout << "Uppercase: " << toUpperCase(text) << endl;
    cout << "Lowercase: " << toLowerCase(text) << endl;
    cout << "Contains 'W'? " << (contains(text, 'W') ? "Yes" : "No") << endl;
    cout << "Word count: " << countWords(text) << endl;
    cout << endl;

    // ---------------------------------------------------------
    // 4. Nested namespace access
    // ---------------------------------------------------------
    cout << "=== Nested Namespace ===" << endl;
    // Full qualification
    cout << "2^10 = " << MathUtils::Advanced::power(2, 10) << endl;

    // Using alias
    cout << "3^4 = " << MathAdv::power(3, 4) << endl;
    cout << endl;

    // ---------------------------------------------------------
    // 5. Inline namespace (C++11) - versioning example
    // ---------------------------------------------------------
    cout << "=== Inline Namespace (Versioning) ===" << endl;
    V1::printVersion();
    V2::printVersion();  // Inline namespace members are visible
    V2::newFeature();
    cout << endl;

    // ---------------------------------------------------------
    // 6. Anonymous namespace (file-local scope)
    // ---------------------------------------------------------
    cout << "=== Anonymous Namespace ===" << endl;
    cout << "Counter: " << getCounter() << endl;
    incrementCounter();
    incrementCounter();
    cout << "Counter after increments: " << getCounter() << endl;
    cout << endl;

    // ---------------------------------------------------------
    // 7. Mixing namespaces (potential for name conflicts)
    // ---------------------------------------------------------
    cout << "=== Name Conflict Demonstration ===" << endl;

    // Add function exists in MathUtils namespace
    cout << "MathUtils::add(3, 4) = " << add(3, 4) << endl;

    // To disambiguate, use qualification
    cout << "MathUtils::add explicitly = " << MathUtils::add(3, 4) << endl;
    cout << endl;

    // ---------------------------------------------------------
    // 8. Namespace with class
    // ---------------------------------------------------------
    cout << "=== Namespace with Class ===" << endl;
    Container::MyVector vec;
    vec.push(10);
    vec.push(20);
    vec.push(30);
    vec.display();
    cout << "Size: " << vec.size() << endl;

    // ---------------------------------------------------------
    // 9. Using namespace for scoping and avoiding conflicts
    // ---------------------------------------------------------
    cout << "\n=== Scoping with Curly Braces ===" << endl;
    {
        using namespace MathUtils;
        cout << "Inside block: square(6) = " << square(6) << endl;
        cout << "Inside block: add(2, 3) = " << add(2, 3) << endl;
    }
    // square and add are no longer accessible here without qualification
    cout << "Outside block: MathUtils::square(6) = " << MathUtils::square(6) << endl;

    return 0;
}

results matching ""

    No results matching ""