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();
|
||||
}
|
||||
|
||||
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
|
||||
|
|
|
@ -25,6 +25,8 @@ namespace duck {
|
|||
class EnvFake : public EnvBase {
|
||||
typedef std::unordered_map<std::string_view, std::string_view> map_type;
|
||||
public:
|
||||
typedef map_type::const_iterator const_iterator;
|
||||
|
||||
explicit EnvFake (bool starts_empty=false);
|
||||
~EnvFake() noexcept = default;
|
||||
|
||||
|
@ -36,6 +38,11 @@ namespace duck {
|
|||
virtual size_type size() const noexcept override;
|
||||
virtual void clear() noexcept override;
|
||||
|
||||
const_iterator begin() const;
|
||||
const_iterator cbegin() const;
|
||||
const_iterator end() const;
|
||||
const_iterator cend() const;
|
||||
|
||||
private:
|
||||
std::unordered_map<std::string_view, std::unique_ptr<char[]>> m_map_strong_cpy;
|
||||
map_type m_map;
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
#include <unordered_map>
|
||||
#include <memory>
|
||||
#include <cassert>
|
||||
#include <utility>
|
||||
#include <cstring>
|
||||
|
||||
#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
|
||||
|
||||
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() :
|
||||
m_name_buff(std::make_unique<char[]>(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
|
||||
|
|
|
@ -19,10 +19,36 @@
|
|||
|
||||
#include "env_base.hpp"
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
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 {
|
||||
public:
|
||||
typedef detail::EnvironIterator const_iterator;
|
||||
|
||||
EnvReal();
|
||||
virtual ~EnvReal() noexcept = default;
|
||||
|
||||
|
@ -34,6 +60,11 @@ namespace duck {
|
|||
virtual size_type size() const noexcept override;
|
||||
virtual void clear() noexcept override;
|
||||
|
||||
const_iterator begin() const;
|
||||
const_iterator cbegin() const;
|
||||
const_iterator end() const;
|
||||
const_iterator cend() const;
|
||||
|
||||
private:
|
||||
const char* raw_fetch_env (std::string_view name) const noexcept;
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ namespace duck {
|
|||
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{""});
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue