summaryrefslogtreecommitdiff
path: root/tools/minicargo/helpers.h
blob: d811f21abaedeb092fd4672022a8b03be06e88ad (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#pragma once

#include <string>

namespace helpers {


/// Path helper class (because I don't want to include boost)
class path
{
#ifdef _WIN32
    const char SEP = '\\';
#else
    const char SEP = '/';
#endif

    ::std::string   m_str;

    path()
    {
    }
public:
    path(const ::std::string& s):
        path(s.c_str())
    {
    }
    path(const char* s):
        m_str(s)
    {
        // 1. Normalise path separators to the system specified separator
        for(size_t i = 0; i < m_str.size(); i ++)
        {
            if( m_str[i] == '/' || m_str[i] == '\\' )
                m_str[i] = SEP;
        }

        // 2. Remove any trailing separators
        if( !m_str.empty() )
        {
            while(!m_str.empty() && m_str.back() == SEP )
                m_str.pop_back();
            if(m_str.empty())
            {
                m_str.push_back(SEP);
            }
        }
        else
        {
            throw ::std::runtime_error("Empty path being constructed");
        }
    }

    path operator/(const path& p) const
    {
        if(p.m_str[0] == '/')
            throw ::std::runtime_error("Appending an absolute path to another path");
        return *this / p.m_str.c_str();
    }
    path operator/(const char* o) const
    {
        auto rv = *this;
        rv.m_str.push_back(SEP);
        rv.m_str.append(o);
        return rv;
    }

    path parent() const
    {
        auto pos = m_str.find_last_of(SEP);
        if(pos == ::std::string::npos)
        {
            return *this;
        }
        else
        {
            path rv;
            rv.m_str = m_str.substr(0, pos);
            return rv;
        }
    }

    operator ::std::string() const
    {
        return m_str;
    }

    friend ::std::ostream& operator<<(::std::ostream& os, const path& p)
    {
        return os << p.m_str;
    }
};

} // namespace helpers