mirror of
https://github.com/matrix-construct/construct
synced 2024-11-29 02:02:38 +01:00
ircd: Move fpe out of util.
This commit is contained in:
parent
f4b3b6f1e0
commit
4371d803a4
6 changed files with 137 additions and 138 deletions
|
@ -1,7 +1,7 @@
|
|||
// Matrix Construct
|
||||
// The Construct
|
||||
//
|
||||
// Copyright (C) Matrix Construct Developers, Authors & Contributors
|
||||
// Copyright (C) 2016-2018 Jason Volk <jason@zemos.net>
|
||||
// Copyright (C) The Construct Developers, Authors & Contributors
|
||||
// Copyright (C) 2016-2020 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
|
||||
|
@ -9,11 +9,9 @@
|
|||
// full license for this software is available in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
#define HAVE_IRCD_UTIL_FPE_H
|
||||
#define HAVE_IRCD_FPE_H
|
||||
|
||||
namespace ircd {
|
||||
inline namespace util {
|
||||
namespace fpe
|
||||
namespace ircd::fpe
|
||||
{
|
||||
struct errors_handle;
|
||||
|
||||
|
@ -23,12 +21,12 @@ namespace fpe
|
|||
|
||||
void throw_errors(const ushort &flags);
|
||||
std::fexcept_t set(const ushort &flag);
|
||||
}}}
|
||||
}
|
||||
|
||||
/// Perform a single floating point operation at a time within the scope
|
||||
/// of fpe::errors_handle. After each operation check the floating point
|
||||
/// unit for an error status flag and throw a C++ exception.
|
||||
struct ircd::util::fpe::errors_handle
|
||||
struct ircd::fpe::errors_handle
|
||||
{
|
||||
std::fexcept_t theirs;
|
||||
|
|
@ -52,6 +52,7 @@
|
|||
#include "run.h"
|
||||
#include "demangle.h"
|
||||
#include "backtrace.h"
|
||||
#include "fpe.h"
|
||||
#include "locale.h"
|
||||
#include "time.h"
|
||||
#include "logger.h"
|
||||
|
|
|
@ -60,7 +60,6 @@ namespace ircd
|
|||
#include "u2a.h"
|
||||
#include "pretty.h"
|
||||
#include "hash.h"
|
||||
#include "fpe.h"
|
||||
#include "closure.h"
|
||||
#include "test.h"
|
||||
#include "boolean.h"
|
||||
|
|
|
@ -118,6 +118,7 @@ libircd_la_SOURCES += exception.cc
|
|||
libircd_la_SOURCES += util.cc
|
||||
libircd_la_SOURCES += demangle.cc
|
||||
libircd_la_SOURCES += backtrace.cc
|
||||
libircd_la_SOURCES += fpe.cc
|
||||
libircd_la_SOURCES += locale.cc
|
||||
libircd_la_SOURCES += timedate.cc
|
||||
libircd_la_SOURCES += lex_cast.cc
|
||||
|
|
128
ircd/fpe.cc
Normal file
128
ircd/fpe.cc
Normal file
|
@ -0,0 +1,128 @@
|
|||
// The Construct
|
||||
//
|
||||
// Copyright (C) The Construct Developers, Authors & Contributors
|
||||
// Copyright (C) 2016-2020 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. The
|
||||
// full license for this software is available in the LICENSE file.
|
||||
|
||||
#ifndef __GNUC__
|
||||
#pragma STDC FENV_ACCESS on
|
||||
#endif
|
||||
|
||||
std::fexcept_t
|
||||
ircd::fpe::set(const ushort &flags)
|
||||
{
|
||||
std::fexcept_t theirs;
|
||||
syscall(std::fesetexceptflag, &theirs, flags);
|
||||
return theirs;
|
||||
}
|
||||
|
||||
void
|
||||
ircd::fpe::throw_errors(const ushort &flags)
|
||||
{
|
||||
if(!flags)
|
||||
return;
|
||||
|
||||
thread_local char buf[128];
|
||||
throw std::domain_error
|
||||
{
|
||||
reflect(buf, flags)
|
||||
};
|
||||
}
|
||||
|
||||
ircd::string_view
|
||||
ircd::fpe::reflect(const mutable_buffer &buf,
|
||||
const ushort &flags)
|
||||
{
|
||||
window_buffer wb{buf};
|
||||
const auto append{[&wb](const auto &flag)
|
||||
{
|
||||
wb([&flag](const mutable_buffer &buf)
|
||||
{
|
||||
return strlcpy(buf, reflect(flag));
|
||||
});
|
||||
}};
|
||||
|
||||
for(size_t i(0); i < sizeof(flags) * 8; ++i)
|
||||
if(flags & (1 << i))
|
||||
append(1 << i);
|
||||
|
||||
return wb.completed();
|
||||
}
|
||||
|
||||
ircd::string_view
|
||||
ircd::fpe::reflect(const ushort &flag)
|
||||
{
|
||||
switch(flag)
|
||||
{
|
||||
case 0: return "";
|
||||
case FE_INVALID: return "INVALID";
|
||||
case FE_DIVBYZERO: return "DIVBYZERO";
|
||||
case FE_UNDERFLOW: return "UNDERFLOW";
|
||||
case FE_OVERFLOW: return "OVERFLOW";
|
||||
case FE_INEXACT: return "INEXACT";
|
||||
}
|
||||
|
||||
return "?????";
|
||||
}
|
||||
|
||||
ircd::string_view
|
||||
ircd::fpe::reflect_sicode(const int &code)
|
||||
{
|
||||
switch(code)
|
||||
{
|
||||
#if defined(HAVE_SIGNAL_H) && defined(FPE_INTDIV)
|
||||
case FPE_INTDIV: return "INTDIV";
|
||||
case FPE_INTOVF: return "INTOVF";
|
||||
case FPE_FLTDIV: return "FLTDIV";
|
||||
case FPE_FLTOVF: return "FLTOVF";
|
||||
case FPE_FLTUND: return "FLTUND";
|
||||
case FPE_FLTRES: return "FLTRES";
|
||||
case FPE_FLTINV: return "FLTINV";
|
||||
case FPE_FLTSUB: return "FLTSUB";
|
||||
#endif // HAVE_SIGNAL_H
|
||||
}
|
||||
|
||||
return "?????";
|
||||
}
|
||||
|
||||
//
|
||||
// errors_handle
|
||||
//
|
||||
|
||||
ircd::fpe::errors_handle::errors_handle()
|
||||
{
|
||||
syscall(std::fegetexceptflag, &theirs, FE_ALL_EXCEPT);
|
||||
clear_pending();
|
||||
}
|
||||
|
||||
ircd::fpe::errors_handle::~errors_handle()
|
||||
noexcept(false)
|
||||
{
|
||||
const auto pending(this->pending());
|
||||
syscall(std::fesetexceptflag, &theirs, FE_ALL_EXCEPT);
|
||||
throw_errors(pending);
|
||||
}
|
||||
|
||||
void
|
||||
ircd::fpe::errors_handle::clear_pending()
|
||||
{
|
||||
syscall(std::feclearexcept, FE_ALL_EXCEPT);
|
||||
}
|
||||
|
||||
void
|
||||
ircd::fpe::errors_handle::throw_pending()
|
||||
const
|
||||
{
|
||||
throw_errors(pending());
|
||||
}
|
||||
|
||||
ushort
|
||||
ircd::fpe::errors_handle::pending()
|
||||
const
|
||||
{
|
||||
return std::fetestexcept(FE_ALL_EXCEPT);
|
||||
}
|
128
ircd/util.cc
128
ircd/util.cc
|
@ -23,134 +23,6 @@ ircd::util::size(std::ostream &s)
|
|||
return ret;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// util/fpe.h
|
||||
//
|
||||
|
||||
#ifndef __GNUC__
|
||||
#pragma STDC FENV_ACCESS on
|
||||
#endif
|
||||
|
||||
std::fexcept_t
|
||||
ircd::util::fpe::set(const ushort &flags)
|
||||
{
|
||||
std::fexcept_t theirs;
|
||||
syscall(std::fesetexceptflag, &theirs, flags);
|
||||
return theirs;
|
||||
}
|
||||
|
||||
void
|
||||
ircd::util::fpe::throw_errors(const ushort &flags)
|
||||
{
|
||||
if(!flags)
|
||||
return;
|
||||
|
||||
thread_local char buf[128];
|
||||
throw std::domain_error
|
||||
{
|
||||
reflect(buf, flags)
|
||||
};
|
||||
}
|
||||
|
||||
ircd::string_view
|
||||
ircd::util::fpe::reflect(const mutable_buffer &buf,
|
||||
const ushort &flags)
|
||||
{
|
||||
window_buffer wb{buf};
|
||||
const auto append{[&wb](const auto &flag)
|
||||
{
|
||||
wb([&flag](const mutable_buffer &buf)
|
||||
{
|
||||
return strlcpy(buf, reflect(flag));
|
||||
});
|
||||
}};
|
||||
|
||||
for(size_t i(0); i < sizeof(flags) * 8; ++i)
|
||||
if(flags & (1 << i))
|
||||
append(1 << i);
|
||||
|
||||
return wb.completed();
|
||||
}
|
||||
|
||||
ircd::string_view
|
||||
ircd::util::fpe::reflect(const ushort &flag)
|
||||
{
|
||||
switch(flag)
|
||||
{
|
||||
case 0: return "";
|
||||
case FE_INVALID: return "INVALID";
|
||||
case FE_DIVBYZERO: return "DIVBYZERO";
|
||||
case FE_UNDERFLOW: return "UNDERFLOW";
|
||||
case FE_OVERFLOW: return "OVERFLOW";
|
||||
case FE_INEXACT: return "INEXACT";
|
||||
}
|
||||
|
||||
return "?????";
|
||||
}
|
||||
|
||||
ircd::string_view
|
||||
ircd::util::fpe::reflect_sicode(const int &code)
|
||||
{
|
||||
switch(code)
|
||||
{
|
||||
#if defined(HAVE_SIGNAL_H) && defined(FPE_INTDIV)
|
||||
case FPE_INTDIV: return "INTDIV";
|
||||
case FPE_INTOVF: return "INTOVF";
|
||||
case FPE_FLTDIV: return "FLTDIV";
|
||||
case FPE_FLTOVF: return "FLTOVF";
|
||||
case FPE_FLTUND: return "FLTUND";
|
||||
case FPE_FLTRES: return "FLTRES";
|
||||
case FPE_FLTINV: return "FLTINV";
|
||||
case FPE_FLTSUB: return "FLTSUB";
|
||||
#endif // HAVE_SIGNAL_H
|
||||
}
|
||||
|
||||
return "?????";
|
||||
}
|
||||
|
||||
//
|
||||
// errors_handle
|
||||
//
|
||||
|
||||
ircd::util::fpe::errors_handle::errors_handle()
|
||||
{
|
||||
syscall(std::fegetexceptflag, &theirs, FE_ALL_EXCEPT);
|
||||
clear_pending();
|
||||
}
|
||||
|
||||
ircd::util::fpe::errors_handle::~errors_handle()
|
||||
noexcept(false)
|
||||
{
|
||||
const auto pending(this->pending());
|
||||
syscall(std::fesetexceptflag, &theirs, FE_ALL_EXCEPT);
|
||||
throw_errors(pending);
|
||||
}
|
||||
|
||||
void
|
||||
ircd::util::fpe::errors_handle::clear_pending()
|
||||
{
|
||||
syscall(std::feclearexcept, FE_ALL_EXCEPT);
|
||||
}
|
||||
|
||||
void
|
||||
ircd::util::fpe::errors_handle::throw_pending()
|
||||
const
|
||||
{
|
||||
throw_errors(pending());
|
||||
}
|
||||
|
||||
ushort
|
||||
ircd::util::fpe::errors_handle::pending()
|
||||
const
|
||||
{
|
||||
return std::fetestexcept(FE_ALL_EXCEPT);
|
||||
}
|
||||
|
||||
#ifndef __GNUC__
|
||||
#pragma STDC FENV_ACCESS off
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// util/env.h
|
||||
|
|
Loading…
Reference in a new issue