#include <iostream>
#include <iomanip>

struct tabber
{
    static unsigned width;
    static unsigned increment;

    unsigned increments = 0;

    tabber() : increments(0) { }
    tabber(const tabber&) = delete;

    tabber(unsigned count) : increments(count) { width += increment * increments; }
    ~tabber() { width -= increments * increment; }

    tabber& operator=(const tabber&) = delete;

    tabber& inc() { ++increments; width += increment; return *this; }
    tabber& dec() { if (increments) { --increments; width -= increment; } return *this; }
};

unsigned tabber::width = 0;
unsigned tabber::increment = 3;

std::ostream& operator<<(std::ostream& os, const tabber& tab)
{
    if ( tabber::width )
        os << std::setw(tabber::width) << ' ';

    return os;
}


float return_value(tabber& t, float value)
{
    std::cout << t.dec() << value << '\n';
    return value;
}

float pow(int base, int power)
{
    tabber t;
    std::cout << t << "pow(" << base << ", " << power << ")\n";
    t.inc();

    if (power == 0)
        return return_value(t, 1.0);

    if (power == 1)
        return return_value(t, base);

    if (base < 0)
    {
        std::cout << t << "base is negative - recalling with positive base.\n";
        return return_value(t, pow(-base, power));
    }

    if (power < 0)
    {
        std::cout << t << "power is negative - recalling with positive power.\n";
        float value = 1.0 / pow(base, -power);

        std::cout << t << "Since power was negative, dividing 1.0 by return value.\n";
        return return_value(t, value);
    }

    return return_value(t, base * pow(base, power - 1));
}

int main()
{
    int base = 2; 
    int power = -3;

    pow(base, power);
}