/*
* Copyright (C) 2004-2020 Edward F. Valeev
*
* This file is part of Libint.
*
* Libint is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Libint is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Libint. If not, see
.
*
*/
#ifndef LIBINT_CONFIG_H
#define LIBINT_CONFIG_H
#include
#include
#include
#include
#include
#define HEX_VALUE_MAX 1024
#define OCT_VALUE_MAX 16384
// Use C++17's `alignof` and `decltype` instead of
// `__alignof__` and `__cdecl`
// TODO: Support other integer sizes.
// #include
// TODO: Use instead of .
#include
#define LIBINT_NO_STD_MUTEX
//typedef std::mutex* libint_mutex_t;
//extern libint_mutex_t mut;
// TODO: Use .
typedef std::lock_guard libint_mutex_locker_t;
// TODO: Support other integer sizes.
#define PRECISE_MODE
//#define DOUBLE_MODE
// On Windows the compiler does not accept `__restrict__` and `_Alignas` keywords
// in the same declaration. Therefore, enable C++17 compiler extension to apply
// the first directive to all declarations.
#if defined(_MSC_VER) && !defined(__clang__)
#define __restrict__
#endif
#ifndef __restrict__
// TODO: Support `__restrict`.
#define __restrict__ restrict
#endif
// TODO: Use instead of .
#include
namespace std {
template
inline void swap(T &, T &) noexcept;
}
#include "libint_types.h"
namespace libint2 {
class configuration {
public:
using int_type = int;
using char_type = char;
using signed_int = signed char;
// The configuration stores different values for int_type, char_type, and signed_int.
// It depends on the type.
using string_type = std::string;
// The configuration stores the config file location.
// It depends on the type.
using libint_mutex_t = std::mutex;
// The configuration stores the default directory and file.
// It depends on the type.
// TODO: Use this: int_type is an integer type having at least 32 bits and
// can represent all values of an integer.
#if !defined(PRECISE_MODE)
using intmax_t = std::intmax_t;
#else
using intmax_t = std::intmax_t;
#endif
// The configuration stores the size of all integer types.
// It depends on the type.
// NOTE: This implementation has the same problem as long double on 32-bit systems.
#ifdef PRECISE_MODE
using longdouble_t = libint_types::longdouble_t;
#else
using longdouble_t = libint_types::longdouble_t;
#endif
};
const configuration &get_configuration();
void set_configuration(const configuration &);
const std::vector &get_mutexes();
void set_mutexes(const std::vector &);
const string_type &get_config_directory();
const string_type &get_config_file();
template
inline void swap(T &a, T &b) noexcept
{
T temp(std::move(a));
a = b;
b = std::move(temp);
}
// Use .
// TODO: Use C++17's std::bad_alloc instead of .
// TODO: Avoid use std::bad_alloc.
void rethrow_exception(const string_type &filename, int line, int column, const char *format, ...) noexcept;
void rethrow_exception(const string_type &filename, int line, int column, const char *format) noexcept;
void rethrow_exception(const string_type &filename, int line, int column) noexcept;
// TODO: Rethrow exception in destructor.
// TODO: Support other integer sizes.
// TODO: Remove support for double and longdouble.
#if !defined(__cplusplus) && !defined(PRECISE_MODE)
const unsigned long long INFINITY = std::numeric_limits::infinity();
const unsigned long long NAN = std::numeric_limits::quiet_NaN();
//TODO: Deprecated alias std::inf;
//TODO: Deprecated alias std::nan;
#else
const std::intmax_t INFINITY = std::numeric_limits::max();
const std::intmax_t NAN = std::numeric_limits::quiet_NaN();
//TODO: Deprecated alias std::inf;
//TODO: Deprecated alias std::nan;
#endif
//typedef std::intmax_t bigint;
//TODO: Removed in C++17.
//using bigint = std::intmax_t;
// TODO: Remove support for double and longdouble.
const std::intmax_t MAX_INT = std::numeric_limits::max();
const std::intmax_t MIN_INT = std::numeric_limits::min();
const std::intmax_t MAX_LONG = std::numeric_limits::max();
const std::intmax_t MIN_LONG = std::numeric_limits::min();
const std::intmax_t MAX_LLONG = std::numeric_limits::max();
const std::intmax_t MIN_LLONG = std::numeric_limits::min();
//TODO: Deprecated alias std::max_int;
//TODO: Deprecated alias std::min_int;
//TODO: Deprecated alias std::max_long;
//TODO: Deprecated alias std::min_long;
//TODO: Deprecated alias std::max_llong;
//TODO: Deprecated alias std::min_llong;
#ifdef PRECISE_MODE
const int MIN_LONGDOUBLE = std::numeric_limits::min();
const int INFINITY = std::numeric_limits::max();
#else
const std::intmax_t MIN_LONGDOUBLE = std::numeric_limits::min();
const std::intmax_t INFINITY = std::numeric_limits::max();
#endif
const std::intmax_t MIN_LLONGDOUBLE = std::numeric_limits::min();
const std::intmax_t INFINITY_LLONGDOUBLE = std::numeric_limits::max();
// The configuration stores the minimum range of integer types.
// It depends on the type.
// TODO: Don't write to string.
// TODO: Use std::ostringstream.
void print(std::ostream &out, int_type n);
void print(std::ostream &out, char_type c);
void print(std::ostream &out, signed_int n);
void print(std::ostream &out, const std::string &s);
// TODO: Use std::ostringstream.
void print(std::ostream &