0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-12-26 15:33:54 +01:00

ircd: Add lex_cast wrapper interface; various cleanup.

This commit is contained in:
Jason Volk 2017-03-14 11:39:26 -07:00
parent 26f59954af
commit c9ddf4f6ab
27 changed files with 505 additions and 240 deletions

View file

@ -81,19 +81,31 @@ struct allocator::fixed<T, size>::state
static constexpr uint word_bits { word_bytes * 8 };
static uint byte(const uint &i) { return i / word_bits; }
static uint bit(const uint &i) { return i % word_bits; }
static word_t mask(const uint &pos) { return word_t(1) << bit(pos); }
bool bt(const uint &pos) const { return avail[byte(pos)] & (1ULL << bit(pos)); }
void bts(const uint &pos) { avail[byte(pos)] |= (1ULL << bit(pos)); }
void btc(const uint &pos) { avail[byte(pos)] &= ~(1ULL << bit(pos)); }
bool test(const uint &pos) const { return avail[byte(pos)] & mask(pos); }
void bts(const uint &pos) { avail[byte(pos)] |= mask(pos); }
void btc(const uint &pos) { avail[byte(pos)] &= ~mask(pos); }
uint next(const size_t &n) const;
allocator::fixed<T, size> operator()() { return { *this }; }
};
template<class... T1,
class... T2>
bool operator==(const allocator::fixed<T1...> &, const allocator::fixed<T2...> &);
template<class... T1,
class... T2>
bool operator!=(const allocator::fixed<T1...> &, const allocator::fixed<T2...> &);
} // namespace ircd
template<class T,
size_t size>
allocator::fixed<T, size>::fixed(state &s)
ircd::allocator::fixed<T, size>::fixed(state &s)
noexcept
:s{&s}
{
@ -103,7 +115,7 @@ template<class T,
size_t size>
template<class U,
size_t S>
allocator::fixed<T, size>::fixed(const fixed<U, S> &)
ircd::allocator::fixed<T, size>::fixed(const fixed<U, S> &)
noexcept
{
assert(0);
@ -112,7 +124,7 @@ noexcept
template<class T,
size_t size>
void
allocator::fixed<T, size>::deallocate(const pointer &p,
ircd::allocator::fixed<T, size>::deallocate(const pointer &p,
const size_type &n)
{
const uint pos(p - s->buf.data());
@ -122,12 +134,12 @@ allocator::fixed<T, size>::deallocate(const pointer &p,
template<class T,
size_t size>
typename allocator::fixed<T, size>::pointer
allocator::fixed<T, size>::allocate(const size_type &n,
typename ircd::allocator::fixed<T, size>::pointer
ircd::allocator::fixed<T, size>::allocate(const size_type &n,
const const_pointer &hint)
{
const auto next(s->next(n));
if(unlikely(next >= size))
if(unlikely(next >= size)) // No block of n was found anywhere (next is past-the-end)
throw std::bad_alloc();
for(size_t i(0); i < n; ++i)
@ -140,31 +152,26 @@ allocator::fixed<T, size>::allocate(const size_type &n,
template<class T,
size_t size>
uint
allocator::fixed<T, size>::state::next(const size_t &n)
ircd::allocator::fixed<T, size>::state::next(const size_t &n)
const
{
// Search for a contiguous block of n, starting from after the last alloc.
uint ret(last), rem(n);
for(; ret < size && rem; ++ret)
if(bt(ret))
if(test(ret))
rem = n;
else
--rem;
// A block of n was found between the last alloc and the end.
if(likely(!rem))
return ret - n;
// Circle around and search between 0 to last
for(ret = 0, rem = n; ret < last && rem; ++ret)
if(bt(ret))
if(test(ret))
rem = n;
else
--rem;
// No block of n was found anywhere, report size past-the-end
// The allocator should throw std::bad_alloc with this value.
if(unlikely(rem))
if(unlikely(rem)) // The allocator should throw std::bad_alloc if !rem
return size;
return ret - n;
@ -172,16 +179,16 @@ const
template<class... T1,
class... T2>
bool operator==(const allocator::fixed<T1...> &a, const allocator::fixed<T2...> &b)
bool
ircd::operator==(const allocator::fixed<T1...> &a, const allocator::fixed<T2...> &b)
{
return &a == &b;
}
template<class... T1,
class... T2>
bool operator!=(const allocator::fixed<T1...> &a, const allocator::fixed<T2...> &b)
bool
ircd::operator!=(const allocator::fixed<T1...> &a, const allocator::fixed<T2...> &b)
{
return &a != &b;
}
} // namespace ircd

View file

@ -119,15 +119,61 @@ struct opts
template<class... list> opts(list&&... l): optlist<opt>{std::forward<list>(l)...} {}
};
struct const_iterator
struct handle
{
struct const_iterator;
private:
std::unique_ptr<struct meta> meta;
std::unique_ptr<rocksdb::DB> d;
public:
using closure = std::function<void (const string_view &)>;
operator bool() const { return bool(d); }
bool operator!() const { return !d; }
// Iterations
const_iterator lower_bound(const string_view &key, const gopts & = {});
const_iterator upper_bound(const string_view &key, const gopts & = {});
const_iterator cbegin(const gopts & = {});
const_iterator cend(const gopts & = {});
// Tests if key exists
bool has(const string_view &key, const gopts & = {});
// Perform a get into a closure. This offers a reference to the data with zero-copy.
void operator()(const string_view &key, const closure &func, const gopts & = {});
void operator()(const string_view &key, const gopts &, const closure &func);
// Get data into your buffer. The signed char buffer is null terminated; the unsigned is not.
size_t get(const string_view &key, char *const &buf, const size_t &max, const gopts & = {});
size_t get(const string_view &key, uint8_t *const &buf, const size_t &max, const gopts & = {});
std::string get(const string_view &key, const gopts & = {});
// Write data to the db
void set(const string_view &key, const string_view &value, const sopts & = {});
void set(const string_view &key, const uint8_t *const &buf, const size_t &size, const sopts & = {});
// Remove data from the db. not_found is never thrown.
void del(const string_view &key, const sopts & = {});
handle(const std::string &name, const opts & = {});
handle();
handle(handle &&) noexcept;
handle &operator=(handle &&) noexcept;
~handle() noexcept;
};
struct handle::const_iterator
{
using key_type = string_view;
using mapped_type = string_view;
using value_type = std::pair<key_type, mapped_type>;
private:
friend class handle;
struct state;
friend class handle;
std::unique_ptr<struct state> state;
mutable value_type val;
@ -156,49 +202,10 @@ struct const_iterator
~const_iterator() noexcept;
};
class handle
{
friend class const_iterator;
std::unique_ptr<struct meta> meta;
std::unique_ptr<rocksdb::DB> d;
public:
using closure = std::function<void (const string_view &)>;
// Iterations
const_iterator lower_bound(const string_view &key, const gopts & = {});
const_iterator upper_bound(const string_view &key, const gopts & = {});
const_iterator cbegin(const gopts & = {});
const_iterator cend(const gopts & = {});
// Tests if key exists
bool has(const string_view &key, const gopts & = {});
// Perform a get into a closure. This offers a reference to the data with zero-copy.
void operator()(const string_view &key, const closure &func, const gopts & = {});
void operator()(const string_view &key, const gopts &, const closure &func);
// Get data into your buffer. The signed char buffer is null terminated; the unsigned is not.
size_t get(const string_view &key, char *const &buf, const size_t &max, const gopts & = {});
size_t get(const string_view &key, uint8_t *const &buf, const size_t &max, const gopts & = {});
std::string get(const string_view &key, const gopts & = {});
// Write data to the db
void set(const string_view &key, const string_view &value, const sopts & = {});
void set(const string_view &key, const uint8_t *const &buf, const size_t &size, const sopts & = {});
// Remove data from the db. not_found is never thrown.
void del(const string_view &key, const sopts & = {});
handle(const std::string &name, const opts & = {});
~handle() noexcept;
};
void write(handle &, const string_view &key, const json::doc &obj, const sopts & = {});
const_iterator begin(handle &);
const_iterator end(handle &);
handle::const_iterator begin(handle &);
handle::const_iterator end(handle &);
struct init
{
@ -212,13 +219,13 @@ extern struct log::log log;
} // namespace db
} // namespace ircd
inline ircd::db::const_iterator
inline ircd::db::handle::const_iterator
ircd::db::end(handle &handle)
{
return handle.cend();
}
inline ircd::db::const_iterator
inline ircd::db::handle::const_iterator
ircd::db::begin(handle &handle)
{
return handle.cbegin();

View file

@ -26,7 +26,6 @@
#pragma once
#define HAVE_IRCD_EXCEPTION_H
#ifdef __cplusplus
namespace ircd {
/** The root exception type.
@ -151,4 +150,3 @@ IRCD_EXCEPTION(exception, error) // throw ircd::error("something bad
IRCD_EXCEPTION(error, user_error) // throw ircd::user_error("something silly")
} // namespace ircd
#endif // __cplusplus

View file

@ -22,7 +22,6 @@
#pragma once
#define HAVE_IRCD_FMT_H
#ifdef __cplusplus
namespace ircd {
namespace fmt {
@ -116,4 +115,3 @@ snprintf::snprintf(char *const &buf,
} // namespace fmt
} // namespace ircd
#endif // __cplusplus

View file

@ -31,7 +31,6 @@
#include "stdinc.h"
#endif
#ifdef __cplusplus
namespace ircd {
extern bool debugmode; // Set by command line to indicate debug behavior
@ -61,7 +60,6 @@ void stop();
void test(const string_view &what);
} // namespace ircd
#endif // __cplusplus

View file

@ -1,45 +0,0 @@
/*
* charybdis: 21st Century IRC++d
* lex_cast.h: Import convenience for boost::lexical_cast
* - This is a non-stdinc.h header, and must be included per-use.
*
* Copyright (C) 2016 Charybdis Development Team
* Copyright (C) 2016 Jason Volk <jason@zemos.net>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice is present in all copies.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#pragma once
#define HAVE_IRCD_LEX_CAST
#include <RB_INC_BOOST_LEXICAL_CAST_HPP
namespace ircd {
inline namespace util {
#ifdef BOOST_LEXICAL_CAST_INCLUDED
template<class T = std::string,
class... Args>
auto lex_cast(Args&&... args)
{
return boost::lexical_cast<T>(std::forward<Args>(args)...);
}
#endif
} // namespace util
} // namespace ircd

View file

@ -21,26 +21,60 @@
*/
#pragma once
#define HAVE_IRCD_STRINGOPS_H
#define HAVE_IRCD_STRING_H
namespace ircd {
// Simple case insensitive comparison convenience utils
bool iequals(const string_view &a, const string_view &b);
bool iless(const string_view &a, const string_view &b);
//
// Lexical conversions
//
// Vintage
size_t strlcpy(char *const &dest, const char *const &src, const size_t &bufmax);
size_t strlcat(char *const &dest, const char *const &src, const size_t &bufmax);
template<class T> bool try_lex_cast(const string_view &);
template<> bool try_lex_cast<long double>(const string_view &);
template<> bool try_lex_cast<double>(const string_view &);
template<> bool try_lex_cast<ulong>(const string_view &);
template<> bool try_lex_cast<long>(const string_view &);
template<> bool try_lex_cast<uint>(const string_view &);
template<> bool try_lex_cast<int>(const string_view &);
template<> bool try_lex_cast<ushort>(const string_view &);
template<> bool try_lex_cast<short>(const string_view &);
template<> bool try_lex_cast<uint8_t>(const string_view &);
template<> bool try_lex_cast<int8_t>(const string_view &);
template<> bool try_lex_cast<bool>(const string_view &);
// Legacy
char *strip_colour(char *string);
char *strip_unprintable(char *string);
char *reconstruct_parv(int parc, const char **parv);
template<class T> T lex_cast(const string_view &);
template<> long double lex_cast(const string_view &);
template<> double lex_cast(const string_view &);
template<> ulong lex_cast(const string_view &);
template<> long lex_cast(const string_view &);
template<> uint lex_cast(const string_view &);
template<> int lex_cast(const string_view &);
template<> ushort lex_cast(const string_view &);
template<> short lex_cast(const string_view &);
template<> uint8_t lex_cast(const string_view &);
template<> int8_t lex_cast(const string_view &);
template<> bool lex_cast(const string_view &);
// User supplied destination buffer
template<class T> string_view lex_cast(T, char *const &buf, const size_t &max);
template<> string_view lex_cast(long double, char *const &buf, const size_t &max);
template<> string_view lex_cast(double, char *const &buf, const size_t &max);
template<> string_view lex_cast(ulong, char *const &buf, const size_t &max);
template<> string_view lex_cast(long, char *const &buf, const size_t &max);
template<> string_view lex_cast(uint, char *const &buf, const size_t &max);
template<> string_view lex_cast(int, char *const &buf, const size_t &max);
template<> string_view lex_cast(ushort, char *const &buf, const size_t &max);
template<> string_view lex_cast(short, char *const &buf, const size_t &max);
template<> string_view lex_cast(uint8_t, char *const &buf, const size_t &max);
template<> string_view lex_cast(int8_t, char *const &buf, const size_t &max);
template<> string_view lex_cast(bool, char *const &buf, const size_t &max);
// Circular static thread_local buffer
const size_t LEX_CAST_BUFS {8};
template<class T> string_view lex_cast(const T &t);
//
// String tokenization utils.
// String tokenization.
//
// Use the closure for best performance. Note that string_view's
@ -96,11 +130,23 @@ string_view token(const string_view &str, const char *const &sep, const size_t &
string_view token_last(const string_view &str, const char *const &sep);
string_view token_first(const string_view &str, const char *const &sep);
//
// Misc utils
//
// Simple case insensitive comparison convenience utils
bool iequals(const string_view &a, const string_view &b);
bool iless(const string_view &a, const string_view &b);
// Vintage
size_t strlcpy(char *const &dest, const char *const &src, const size_t &bufmax);
size_t strlcat(char *const &dest, const char *const &src, const size_t &bufmax);
// Legacy
char *strip_colour(char *string);
char *strip_unprintable(char *string);
char *reconstruct_parv(int parc, const char **parv);
string_view chomp(const string_view &str, const string_view &c = " "s);
std::pair<string_view, string_view> split(const string_view &str, const string_view &delim = " "s);
std::pair<string_view, string_view> rsplit(const string_view &str, const string_view &delim = " "s);
@ -113,6 +159,14 @@ bool startswith(const string_view &str, const char &val);
} // namespace ircd
template<class T>
ircd::string_view
ircd::lex_cast(const T &t)
{
return lex_cast<T>(t, nullptr, 0);
}
inline bool
ircd::startswith(const string_view &str,
const char &val)

View file

@ -22,7 +22,6 @@
#pragma once
#define HAVE_IRCD_LIFE_GUARD_H
#ifdef __cplusplus
namespace ircd {
// Tests if type inherits from std::enable_shared_from_this<>
@ -122,4 +121,3 @@ shared_from(const T &t)
};
} // namespace ircd
#endif // __cplusplus

View file

@ -34,20 +34,17 @@
#pragma once
#define HAVE_IRCD_LOGGER_H
#ifdef __cplusplus
namespace ircd {
const char *smalldate(const time_t &);
} // namespace ircd
#endif // __cplusplus
// windows.h #define conflicts with our facility
#ifdef HAVE_WINDOWS_H
#undef ERROR
#endif
#ifdef __cplusplus
namespace ircd {
namespace log {
@ -160,4 +157,3 @@ template<class... A> void slog(const ilogfile, const uint sno, const char *fmt,
#pragma GCC diagnostic pop
} // namespace ircd
#endif // __cplusplus

View file

@ -22,7 +22,6 @@
#pragma once
#define HAVE_IRCD_MAPI_H
#ifdef __cplusplus
namespace ircd {
namespace mapi {
@ -102,4 +101,3 @@ const
} // namespace mapi
} // namespace ircd
#endif // __cplusplus

View file

@ -36,7 +36,6 @@
* AUTOMODPATH = directory for autoloaded modules
*/
#ifdef __cplusplus
namespace ircd {
namespace path {
@ -97,4 +96,3 @@ void chdir(const std::string &path);
} // namespace path
} // namespace ircd
#endif // __cplusplus

View file

@ -22,7 +22,6 @@
#pragma once
#define HAVE_IRCD_RFC1459_GEN_H
#ifdef __cplusplus
#include <boost/spirit/include/karma.hpp>
#include "rfc1459_parse.h"
@ -156,4 +155,3 @@ rfc1459::gen::grammar<it, top>::grammar(karma::rule<it, top> &top_rule)
} // namespace gen
} // namespace rfc1459
} // namespace ircd
#endif // __cplusplus

View file

@ -22,7 +22,6 @@
#pragma once
#define HAVE_IRCD_RFC1459_PARSE_H
#ifdef __cplusplus
#include <boost/spirit/include/qi.hpp>
BOOST_FUSION_ADAPT_STRUCT
@ -221,4 +220,3 @@ extern const capstan;
} // namespace parse
} // namespace rfc1459
} // namespace ircd
#endif // __cplusplus

View file

@ -157,14 +157,14 @@ struct line {};
} // namespace ircd
#include "util.h"
#include "util_timer.h"
#include "timer.h"
#include "allocator.h"
#include "info.h"
#include "localee.h"
#include "life_guard.h"
#include "exception.h"
#include "color.h"
#include "stringops.h"
#include "lexical.h"
#include "buffer.h"
#include "parse.h"
#include "rfc1459.h"

View file

@ -23,8 +23,6 @@
#pragma once
#define HAVE_IRCD_UTIL_TIMER_H
#ifdef __cplusplus
namespace ircd {
inline namespace util {
@ -91,4 +89,3 @@ const
} // namespace util
} // namespace ircd
#endif // __cplusplus

View file

@ -123,19 +123,6 @@ for_each(const std::function<void (const Enum &)> &func)
}
struct case_insensitive_less
{
bool operator()(const std::string_view &a, const std::string_view &b) const
{
return std::lexicographical_compare(begin(a), end(a), begin(b), end(b), []
(const char &a, const char &b)
{
return tolower(a) < tolower(b);
});
}
};
/**
* flag-enum utilities
*

View file

@ -28,7 +28,7 @@ libircd_la_SOURCES = \
info.cc \
exception.cc \
rfc1459.cc \
stringops.cc \
lexical.cc \
logger.cc \
fs.cc \
mods.cc \

View file

@ -26,7 +26,6 @@
*/
#include <ircd/socket.h>
#include <ircd/lex_cast.h>
namespace ircd {

View file

@ -146,9 +146,33 @@ catch(const std::exception &e)
e.what());
}
db::handle::handle()
{
}
db::handle::handle(handle &&other)
noexcept
:meta{std::move(other.meta)}
,d{std::move(other.d)}
{
}
db::handle &
db::handle::operator=(handle &&other)
noexcept
{
meta = std::move(other.meta);
d = std::move(other.d);
return *this;
}
db::handle::~handle()
noexcept
{
if(!*this)
return;
// Branch not taken after std::move()
log.info("Closing database \"%s\" @ `%s' (handle: %p)",
meta->name.c_str(),
meta->path.c_str(),
@ -306,7 +330,7 @@ db::handle::has(const string_view &key,
namespace ircd {
namespace db {
struct const_iterator::state
struct handle::const_iterator::state
{
struct handle *handle;
rocksdb::ReadOptions ropts;
@ -319,13 +343,13 @@ struct const_iterator::state
} // namespace db
} // namespace ircd
db::const_iterator
db::handle::const_iterator
db::handle::cend(const gopts &gopts)
{
return {};
}
db::const_iterator
db::handle::const_iterator
db::handle::cbegin(const gopts &gopts)
{
const_iterator ret
@ -341,7 +365,7 @@ db::handle::cbegin(const gopts &gopts)
return std::move(ret);
}
db::const_iterator
db::handle::const_iterator
db::handle::upper_bound(const string_view &key,
const gopts &gopts)
{
@ -355,7 +379,7 @@ db::handle::upper_bound(const string_view &key,
return std::move(it);
}
db::const_iterator
db::handle::const_iterator
db::handle::lower_bound(const string_view &key,
const gopts &gopts)
{
@ -375,7 +399,7 @@ db::handle::lower_bound(const string_view &key,
return std::move(ret);
}
db::const_iterator::state::state(struct handle *const &handle,
db::handle::const_iterator::state::state(db::handle *const &handle,
const gopts &gopts)
:handle{handle}
,ropts{make_opts(gopts, true)}
@ -383,7 +407,7 @@ db::const_iterator::state::state(struct handle *const &handle,
{
[this, &handle, &gopts]() -> const rocksdb::Snapshot *
{
if(handle && !has_opt(gopts, get::NO_SNAPSHOT))
if(handle && !has_opt(gopts, db::get::NO_SNAPSHOT))
ropts.snapshot = handle->d->GetSnapshot();
return ropts.snapshot;
@ -397,38 +421,38 @@ db::const_iterator::state::state(struct handle *const &handle,
{
}
db::const_iterator::const_iterator(std::unique_ptr<struct state> &&state)
db::handle::const_iterator::const_iterator(std::unique_ptr<struct state> &&state)
:state{std::move(state)}
{
}
db::const_iterator::const_iterator(const_iterator &&o)
db::handle::const_iterator::const_iterator(const_iterator &&o)
noexcept
:state{std::move(o.state)}
{
}
db::const_iterator::~const_iterator()
db::handle::const_iterator::~const_iterator()
noexcept
{
}
db::const_iterator &
db::const_iterator::operator--()
db::handle::const_iterator &
db::handle::const_iterator::operator--()
{
seek(*state->handle->d, pos::PREV, state->ropts, state->it);
return *this;
}
db::const_iterator &
db::const_iterator::operator++()
db::handle::const_iterator &
db::handle::const_iterator::operator++()
{
seek(*state->handle->d, pos::NEXT, state->ropts, state->it);
return *this;
}
const db::const_iterator::value_type &
db::const_iterator::operator*()
const db::handle::const_iterator::value_type &
db::handle::const_iterator::operator*()
const
{
const auto &k(state->it->key());
@ -440,36 +464,36 @@ const
return val;
}
const db::const_iterator::value_type *
db::const_iterator::operator->()
const db::handle::const_iterator::value_type *
db::handle::const_iterator::operator->()
const
{
return &operator*();
}
bool
db::const_iterator::operator>=(const const_iterator &o)
db::handle::const_iterator::operator>=(const const_iterator &o)
const
{
return (*this > o) || (*this == o);
}
bool
db::const_iterator::operator<=(const const_iterator &o)
db::handle::const_iterator::operator<=(const const_iterator &o)
const
{
return (*this < o) || (*this == o);
}
bool
db::const_iterator::operator!=(const const_iterator &o)
db::handle::const_iterator::operator!=(const const_iterator &o)
const
{
return !(*this == o);
}
bool
db::const_iterator::operator==(const const_iterator &o)
db::handle::const_iterator::operator==(const const_iterator &o)
const
{
if(*this && o)
@ -486,7 +510,7 @@ const
}
bool
db::const_iterator::operator>(const const_iterator &o)
db::handle::const_iterator::operator>(const const_iterator &o)
const
{
if(*this && o)
@ -507,7 +531,7 @@ const
}
bool
db::const_iterator::operator<(const const_iterator &o)
db::handle::const_iterator::operator<(const const_iterator &o)
const
{
if(*this && o)
@ -528,7 +552,7 @@ const
}
bool
db::const_iterator::operator!()
db::handle::const_iterator::operator!()
const
{
if(!state)
@ -543,7 +567,7 @@ const
return false;
}
db::const_iterator::operator bool()
db::handle::const_iterator::operator bool()
const
{
return !!*this;

View file

@ -21,7 +21,6 @@
#include <ircd/rfc1459_parse.h>
#include <ircd/rfc1459_gen.h>
#include <ircd/lex_cast.h>
#include <ircd/fmt.h>
BOOST_FUSION_ADAPT_STRUCT

View file

@ -23,7 +23,6 @@
#include <boost/fusion/include/std_pair.hpp>
#include <boost/fusion/adapted/std_pair.hpp>
#include <boost/fusion/adapted/std_tuple.hpp>
#include <ircd/lex_cast.h>
BOOST_FUSION_ADAPT_STRUCT
(

View file

@ -26,7 +26,6 @@
#include <boost/fusion/include/std_pair.hpp>
#include <boost/fusion/adapted/std_pair.hpp>
#include <boost/fusion/adapted/std_tuple.hpp>
#include <ircd/lex_cast.h>
BOOST_FUSION_ADAPT_STRUCT
(
@ -642,14 +641,8 @@ void
ircd::json::obj::delta::set(const int32_t &number)
{
static const size_t max(16);
using array = std::array<char, max>;
std::unique_ptr<char[]> restart(new char[max]);
auto &a(*reinterpret_cast<array *>(restart.get()));
a = lex_cast<array>(number);
const auto size(strlen(restart.get()));
commit(string_view(restart.get(), restart.get() + size));
commit(lex_cast(number, restart.get(), max));
member->owns_second = true;
restart.release();
}
@ -658,14 +651,8 @@ void
ircd::json::obj::delta::set(const uint64_t &number)
{
static const size_t max(32);
using array = std::array<char, max>;
std::unique_ptr<char[]> restart(new char[max]);
auto &a(*reinterpret_cast<array *>(restart.get()));
a = lex_cast<array>(number);
const auto size(strlen(restart.get()));
commit(string_view(restart.get(), restart.get() + size));
commit(lex_cast(number, restart.get(), max));
member->owns_second = true;
restart.release();
}
@ -674,14 +661,8 @@ void
ircd::json::obj::delta::set(const double &number)
{
static const size_t max(64);
using array = std::array<char, max>;
std::unique_ptr<char[]> restart(new char[max]);
auto &a(*reinterpret_cast<array *>(restart.get()));
a = lex_cast<array>(number);
const auto size(strlen(restart.get()));
commit(string_view(restart.get(), restart.get() + size));
commit(lex_cast(number, restart.get(), max));
member->owns_second = true;
restart.release();
}

View file

@ -21,6 +21,7 @@
*/
#include <RB_INC_BOOST_TOKENIZER_HPP
#include <RB_INC_BOOST_LEXICAL_CAST_HPP
ircd::string_view
ircd::token_first(const string_view &str,
@ -138,6 +139,285 @@ ircd::tokens(const string_view &str,
std::for_each(begin(view), end(view), closure);
}
namespace ircd {
const size_t LEX_CAST_BUFSIZE {64};
thread_local char lex_cast_buf[LEX_CAST_BUFS][LEX_CAST_BUFSIZE];
template<size_t N,
class T>
static string_view
_lex_cast(const T &i,
char *buf,
size_t max)
{
using array = std::array<char, N>;
if(!buf)
{
static thread_local uint cur;
buf = lex_cast_buf[cur++];
max = LEX_CAST_BUFSIZE;
cur %= LEX_CAST_BUFS;
}
assert(max >= N);
auto &a(*reinterpret_cast<array *>(buf));
a = boost::lexical_cast<array>(i);
return { buf, strnlen(buf, max) };
}
template<class T>
static T
_lex_cast(const string_view &s)
{
return boost::lexical_cast<T>(s);
}
} // namespace ircd
template<> ircd::string_view
ircd::lex_cast(bool i,
char *const &buf,
const size_t &max)
{
static const size_t MAX(8);
return _lex_cast<MAX>(i, buf, max);
}
template<> ircd::string_view
ircd::lex_cast(int8_t i,
char *const &buf,
const size_t &max)
{
static const size_t MAX(8);
return _lex_cast<MAX>(i, buf, max);
}
template<> ircd::string_view
ircd::lex_cast(uint8_t i,
char *const &buf,
const size_t &max)
{
static const size_t MAX(8);
return _lex_cast<MAX>(i, buf, max);
}
template<> ircd::string_view
ircd::lex_cast(short i,
char *const &buf,
const size_t &max)
{
static const size_t MAX(8);
return _lex_cast<MAX>(i, buf, max);
}
template<> ircd::string_view
ircd::lex_cast(ushort i,
char *const &buf,
const size_t &max)
{
static const size_t MAX(8);
return _lex_cast<MAX>(i, buf, max);
}
template<> ircd::string_view
ircd::lex_cast(int i,
char *const &buf,
const size_t &max)
{
static const size_t MAX(16);
return _lex_cast<MAX>(i, buf, max);
}
template<> ircd::string_view
ircd::lex_cast(uint i,
char *const &buf,
const size_t &max)
{
static const size_t MAX(16);
return _lex_cast<MAX>(i, buf, max);
}
template<> ircd::string_view
ircd::lex_cast(long i,
char *const &buf,
const size_t &max)
{
static const size_t MAX(32);
return _lex_cast<MAX>(i, buf, max);
}
template<> ircd::string_view
ircd::lex_cast(ulong i,
char *const &buf,
const size_t &max)
{
static const size_t MAX(32);
return _lex_cast<MAX>(i, buf, max);
}
template<> ircd::string_view
ircd::lex_cast(double i,
char *const &buf,
const size_t &max)
{
static const size_t MAX(64);
return _lex_cast<MAX>(i, buf, max);
}
template<> ircd::string_view
ircd::lex_cast(long double i,
char *const &buf,
const size_t &max)
{
static const size_t MAX(64);
return _lex_cast<MAX>(i, buf, max);
}
template<> bool
ircd::lex_cast(const string_view &s)
{
return _lex_cast<bool>(s);
}
template<> int8_t
ircd::lex_cast(const string_view &s)
{
return _lex_cast<char>(s);
}
template<> uint8_t
ircd::lex_cast(const string_view &s)
{
return _lex_cast<unsigned char>(s);
}
template<> short
ircd::lex_cast(const string_view &s)
{
return _lex_cast<short>(s);
}
template<> unsigned short
ircd::lex_cast(const string_view &s)
{
return _lex_cast<unsigned short>(s);
}
template<> int
ircd::lex_cast(const string_view &s)
{
return _lex_cast<int>(s);
}
template<> unsigned int
ircd::lex_cast(const string_view &s)
{
return _lex_cast<unsigned int>(s);
}
template<> long
ircd::lex_cast(const string_view &s)
{
return _lex_cast<long>(s);
}
template<> unsigned long
ircd::lex_cast(const string_view &s)
{
return _lex_cast<unsigned long>(s);
}
template<> double
ircd::lex_cast(const string_view &s)
{
return _lex_cast<double>(s);
}
template<> long double
ircd::lex_cast(const string_view &s)
{
return _lex_cast<long double>(s);
}
template<> bool
ircd::try_lex_cast<bool>(const string_view &s)
{
bool i;
return boost::conversion::try_lexical_convert(s, i);
}
template<> bool
ircd::try_lex_cast<int8_t>(const string_view &s)
{
int8_t i;
return boost::conversion::try_lexical_convert(s, i);
}
template<> bool
ircd::try_lex_cast<uint8_t>(const string_view &s)
{
uint8_t i;
return boost::conversion::try_lexical_convert(s, i);
}
template<> bool
ircd::try_lex_cast<short>(const string_view &s)
{
short i;
return boost::conversion::try_lexical_convert(s, i);
}
template<> bool
ircd::try_lex_cast<ushort>(const string_view &s)
{
ushort i;
return boost::conversion::try_lexical_convert(s, i);
}
template<> bool
ircd::try_lex_cast<int>(const string_view &s)
{
int i;
return boost::conversion::try_lexical_convert(s, i);
}
template<> bool
ircd::try_lex_cast<unsigned int>(const string_view &s)
{
unsigned int i;
return boost::conversion::try_lexical_convert(s, i);
}
template<> bool
ircd::try_lex_cast<long>(const string_view &s)
{
long i;
return boost::conversion::try_lexical_convert(s, i);
}
template<> bool
ircd::try_lex_cast<unsigned long>(const string_view &s)
{
unsigned long i;
return boost::conversion::try_lexical_convert(s, i);
}
template<> bool
ircd::try_lex_cast<double>(const string_view &s)
{
double i;
return boost::conversion::try_lexical_convert(s, i);
}
template<> bool
ircd::try_lex_cast<long double>(const string_view &s)
{
long double i;
return boost::conversion::try_lexical_convert(s, i);
}
/*
* strip_colour - remove colour codes from a string
* -asuffield (?)

View file

@ -19,8 +19,6 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <ircd/lex_cast.h>
namespace ircd {
namespace m {

View file

@ -19,7 +19,6 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <ircd/lex_cast.h>
#include <ircd/ctx/continuation.h>
#include <ircd/socket.h>
@ -116,7 +115,7 @@ ircd::socket::socket(const std::string &host,
[&host, &port]() -> ip::tcp::endpoint
{
assert(resolver);
const ip::tcp::resolver::query query(host, lex_cast(port));
const ip::tcp::resolver::query query(host, string(lex_cast(port)));
auto epit(resolver->async_resolve(query, yield(continuation())));
static const ip::tcp::resolver::iterator end;
if(epit == end)

View file

@ -21,7 +21,6 @@
#include <boost/asio.hpp>
#include <ircd/ctx/continuation.h>
#include <ircd/lex_cast.h>
#include <ircd/socket.h>
using namespace ircd;