Implement const_iterators.
Note that they are not available in the base class.
This commit is contained in:
parent
351e84b04e
commit
dfefed1516
5 changed files with 119 additions and 2 deletions
|
@ -126,4 +126,19 @@ void EnvFake::clear() noexcept {
|
||||||
m_map_strong_cpy.clear();
|
m_map_strong_cpy.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto EnvFake::begin() const -> const_iterator {
|
||||||
|
return m_map.cbegin();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto EnvFake::cbegin() const -> const_iterator {
|
||||||
|
return m_map.cbegin();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto EnvFake::end() const -> const_iterator {
|
||||||
|
return m_map.cend();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto EnvFake::cend() const -> const_iterator {
|
||||||
|
return m_map.cend();
|
||||||
|
}
|
||||||
} //namespace duck
|
} //namespace duck
|
||||||
|
|
|
@ -25,6 +25,8 @@ namespace duck {
|
||||||
class EnvFake : public EnvBase {
|
class EnvFake : public EnvBase {
|
||||||
typedef std::unordered_map<std::string_view, std::string_view> map_type;
|
typedef std::unordered_map<std::string_view, std::string_view> map_type;
|
||||||
public:
|
public:
|
||||||
|
typedef map_type::const_iterator const_iterator;
|
||||||
|
|
||||||
explicit EnvFake (bool starts_empty=false);
|
explicit EnvFake (bool starts_empty=false);
|
||||||
~EnvFake() noexcept = default;
|
~EnvFake() noexcept = default;
|
||||||
|
|
||||||
|
@ -36,6 +38,11 @@ namespace duck {
|
||||||
virtual size_type size() const noexcept override;
|
virtual size_type size() const noexcept override;
|
||||||
virtual void clear() noexcept override;
|
virtual void clear() noexcept override;
|
||||||
|
|
||||||
|
const_iterator begin() const;
|
||||||
|
const_iterator cbegin() const;
|
||||||
|
const_iterator end() const;
|
||||||
|
const_iterator cend() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unordered_map<std::string_view, std::unique_ptr<char[]>> m_map_strong_cpy;
|
std::unordered_map<std::string_view, std::unique_ptr<char[]>> m_map_strong_cpy;
|
||||||
map_type m_map;
|
map_type m_map;
|
||||||
|
|
|
@ -27,7 +27,6 @@
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <utility>
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
#if defined(__GNU_LIBRARY__) && ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 17) || __GLIBC__ > 2)
|
#if defined(__GNU_LIBRARY__) && ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 17) || __GLIBC__ > 2)
|
||||||
|
@ -149,8 +148,56 @@ namespace {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::pair<std::string_view, std::string_view> to_pair (char* env_entry) noexcept {
|
||||||
|
std::string_view text(to_string_view(env_entry));
|
||||||
|
const auto eq_pos = text.find('=');
|
||||||
|
if (eq_pos == text.npos) {
|
||||||
|
assert(false);
|
||||||
|
return {"", ""};
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::make_pair(
|
||||||
|
text.substr(0, eq_pos),
|
||||||
|
text.substr(eq_pos + 1)
|
||||||
|
);
|
||||||
|
}
|
||||||
} //unnamed namespace
|
} //unnamed namespace
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
EnvironIterator::EnvironIterator (char** env) noexcept :
|
||||||
|
m_curr(),
|
||||||
|
m_env(env),
|
||||||
|
m_dirty(true)
|
||||||
|
{
|
||||||
|
assert(m_env);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto EnvironIterator::operator*() noexcept -> value_type& {
|
||||||
|
return *this->operator->();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto EnvironIterator::operator->() noexcept -> value_type* {
|
||||||
|
if (m_dirty) {
|
||||||
|
m_curr = (m_env and *m_env ? to_pair(*m_env) : value_type());
|
||||||
|
m_dirty = false;
|
||||||
|
}
|
||||||
|
return &m_curr;
|
||||||
|
}
|
||||||
|
|
||||||
|
EnvironIterator EnvironIterator::operator++(int) noexcept {
|
||||||
|
EnvironIterator cpy(*this);
|
||||||
|
++(*this);
|
||||||
|
return cpy;
|
||||||
|
}
|
||||||
|
|
||||||
|
EnvironIterator EnvironIterator::operator--(int) noexcept {
|
||||||
|
EnvironIterator cpy(*this);
|
||||||
|
--(*this);
|
||||||
|
return cpy;
|
||||||
|
}
|
||||||
|
} //namespace detial
|
||||||
|
|
||||||
EnvReal::EnvReal() :
|
EnvReal::EnvReal() :
|
||||||
m_name_buff(std::make_unique<char[]>(g_name_buff_len)),
|
m_name_buff(std::make_unique<char[]>(g_name_buff_len)),
|
||||||
m_name_buff_len(g_name_buff_len)
|
m_name_buff_len(g_name_buff_len)
|
||||||
|
@ -251,4 +298,21 @@ const char* EnvReal::raw_fetch_env (std::string_view name) const noexcept {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto EnvReal::begin() const -> const_iterator {
|
||||||
|
return {::environ};
|
||||||
|
}
|
||||||
|
|
||||||
|
auto EnvReal::cbegin() const -> const_iterator {
|
||||||
|
return {::environ};
|
||||||
|
}
|
||||||
|
|
||||||
|
auto EnvReal::end() const -> const_iterator {
|
||||||
|
assert(*(::environ + this->size()) == nullptr);
|
||||||
|
return {::environ + this->size()};
|
||||||
|
}
|
||||||
|
|
||||||
|
auto EnvReal::cend() const -> const_iterator {
|
||||||
|
assert(*(::environ + this->size()) == nullptr);
|
||||||
|
return {::environ + this->size()};
|
||||||
|
}
|
||||||
} //namespace duck
|
} //namespace duck
|
||||||
|
|
|
@ -19,10 +19,36 @@
|
||||||
|
|
||||||
#include "env_base.hpp"
|
#include "env_base.hpp"
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
namespace duck {
|
namespace duck {
|
||||||
|
namespace detail {
|
||||||
|
class EnvironIterator {
|
||||||
|
public:
|
||||||
|
typedef std::pair<std::string_view, std::string_view> value_type;
|
||||||
|
|
||||||
|
EnvironIterator (char** env) noexcept;
|
||||||
|
value_type& operator*() noexcept;
|
||||||
|
value_type* operator->() noexcept;
|
||||||
|
|
||||||
|
bool operator== (const EnvironIterator& other) const { return m_env == other.m_env; }
|
||||||
|
bool operator!= (const EnvironIterator& other) const { return m_env != other.m_env; }
|
||||||
|
EnvironIterator& operator++() noexcept { ++m_env; m_dirty = true; return *this; }
|
||||||
|
EnvironIterator& operator--() noexcept { --m_env; m_dirty = true; return *this; }
|
||||||
|
EnvironIterator operator++(int) noexcept;
|
||||||
|
EnvironIterator operator--(int) noexcept;
|
||||||
|
|
||||||
|
private:
|
||||||
|
value_type m_curr;
|
||||||
|
char** m_env;
|
||||||
|
bool m_dirty;
|
||||||
|
};
|
||||||
|
} //namespace detail
|
||||||
|
|
||||||
class EnvReal : public EnvBase {
|
class EnvReal : public EnvBase {
|
||||||
public:
|
public:
|
||||||
|
typedef detail::EnvironIterator const_iterator;
|
||||||
|
|
||||||
EnvReal();
|
EnvReal();
|
||||||
virtual ~EnvReal() noexcept = default;
|
virtual ~EnvReal() noexcept = default;
|
||||||
|
|
||||||
|
@ -34,6 +60,11 @@ namespace duck {
|
||||||
virtual size_type size() const noexcept override;
|
virtual size_type size() const noexcept override;
|
||||||
virtual void clear() noexcept override;
|
virtual void clear() noexcept override;
|
||||||
|
|
||||||
|
const_iterator begin() const;
|
||||||
|
const_iterator cbegin() const;
|
||||||
|
const_iterator end() const;
|
||||||
|
const_iterator cend() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const char* raw_fetch_env (std::string_view name) const noexcept;
|
const char* raw_fetch_env (std::string_view name) const noexcept;
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@ namespace duck {
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string_view to_string_view (const char* str) {
|
inline std::string_view to_string_view (const char* str) noexcept {
|
||||||
return (str ? std::string_view{str} : std::string_view{""});
|
return (str ? std::string_view{str} : std::string_view{""});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue