Browse Source

Meta: Improve project when used as a dependency

master
Riyyi 12 months ago
parent
commit
79ede83a99
  1. 33
      src/blaze/ast.h
  2. 6
      src/blaze/env/macro.h
  3. 2
      src/blaze/forward.h
  4. 62
      src/blaze/to-from-hashmap.h
  5. 10
      src/blaze/util.h

33
src/blaze/ast.h

@ -11,16 +11,18 @@
#include <functional> // std::function
#include <list>
#include <map>
#include <memory> // std::shared_ptr
#include <memory> // std::make_shared, std::shared_ptr
#include <span>
#include <string>
#include <string_view>
#include <typeinfo> // typeid
#include <utility> // std::forward
#include <vector>
#include "ruc/format/formatter.h"
#include "blaze/forward.h"
#include "blaze/to-from-hashmap.h"
namespace blaze {
@ -77,13 +79,12 @@ protected:
#define WITH_META(Type) \
virtual ValuePtr withMetaImpl(ValuePtr meta) const override \
{ \
return makePtr<Type>(*this, meta); \
return std::make_shared<Type>(*this, meta); \
}
#define WITH_NO_META() \
virtual ValuePtr withMetaImpl(ValuePtr meta) const override \
virtual ValuePtr withMetaImpl(ValuePtr) const override \
{ \
(void)meta; \
return nullptr; \
}
@ -195,6 +196,20 @@ public:
HashMap(const HashMap& that, ValuePtr meta);
virtual ~HashMap() = default;
static HashMapPtr create(const Elements& elements)
{
return std::make_shared<HashMap>(elements);
}
// Customization Point
template<typename T>
static HashMapPtr create(T value)
{
HashMapPtr hash_map;
to_hash_map(hash_map, std::forward<T>(value));
return hash_map;
}
static std::string getKeyString(ValuePtr key);
bool exists(const std::string& key);
@ -222,6 +237,11 @@ public:
String(char character);
virtual ~String() = default;
static ValuePtr create(const std::string& data)
{
return std::make_shared<String>(data);
}
const std::string& data() const { return m_data; }
size_t size() const { return m_data.size(); }
bool empty() const { return m_data.empty(); }
@ -287,6 +307,11 @@ public:
Decimal(double decimal);
virtual ~Decimal() = default;
static ValuePtr create(float value)
{
return std::make_shared<Decimal>(value);
}
double decimal() const { return m_decimal; }
WITH_NO_META();

6
src/blaze/env/macro.h vendored

@ -6,15 +6,17 @@
#pragma once
#include <iterator> // std::distance
#include <unordered_map>
#include "blaze/env/environment.h"
#include "blaze/forward.h"
#define ADD_FUNCTION(name, signature, documentation, lambda) \
Environment::registerFunction( \
blaze::Environment::registerFunction( \
{ name, \
signature, \
documentation, \
[](ValueVectorConstIt begin, ValueVectorConstIt end) -> blaze::ValuePtr lambda });
[](blaze::ValueVectorConstIt begin, blaze::ValueVectorConstIt end) -> blaze::ValuePtr lambda });
#define SIZE() std::distance(begin, end)

2
src/blaze/forward.h

@ -15,7 +15,9 @@ namespace blaze {
// Types
class Value;
class HashMap;
typedef std::shared_ptr<Value> ValuePtr;
typedef std::shared_ptr<HashMap> HashMapPtr;
typedef std::vector<ValuePtr> ValueVector;
typedef ValueVector::iterator ValueVectorIt;
typedef ValueVector::reverse_iterator ValueVectorReverseIt;

62
src/blaze/to-from-hashmap.h

@ -0,0 +1,62 @@
/*
* Copyright (C) 2023 Riyyi
*
* SPDX-License-Identifier: MIT
*/
#pragma once
#include <utility> // std::forward
#include "ruc/meta/odr.h"
namespace blaze {
namespace detail {
// struct hashMapConstructor {
// template<typename HashMap>
// static void construct(HashMap& hash_map, bool boolean)
// {
// //..
// }
// };
// template<typename HashMap, typename T>
// void toHashMap(HashMap& hash_map, const T& value)
// {
// hashMapConstructor::construct(hash_map, value);
// }
struct toHashMapFunction {
template<typename HashMapPtr, typename T>
auto operator()(HashMapPtr& hash_map, T&& value) const
{
return to_hash_map(hash_map, std::forward<T>(value));
}
};
} // namespace detail
// Anonymous namespace prevents multiple definition of the reference
namespace {
// Function object
constexpr const auto& to_hash_map = ruc::detail::staticConst<detail::toHashMapFunction>; // NOLINT(misc-definitions-in-headers,clang-diagnostic-unused-variable)
} // namespace
} // namespace blaze
// Customization Points
// https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html
// blaze::to_hash_map is a function object, the type of which is
// blaze::detail::toHashMapFunction. In the blaze::detail namespace are the to_hash_map
// free functions. The function call operator of toHashMapFunction makes an
// unqualified call to to_hash_map which, since it shares the detail namespace with
// the to_hash_map free functions, will consider those in addition to any overloads
// that are found by argument-dependent lookup.
// Variable templates are linked externally, therefor every translation unit
// will see the same address for detail::staticConst<detail::toHashMapFunction>.
// Since blaze::to_hash_map is a reference to the variable template, it too will have
// the same address in all translation units.

10
src/blaze/util.h

@ -36,7 +36,7 @@
#define CHECK_ARG_COUNT_IS_IMPL(name, size, expected, result) \
if (size != expected) { \
Error::the().add(::format("wrong number of arguments: {}, {}", name, size)); \
blaze::Error::the().add(::format("wrong number of arguments: {}, {}", name, size)); \
return result; \
}
@ -54,7 +54,7 @@
#define CHECK_ARG_COUNT_AT_LEAST_IMPL(name, size, min, result) \
if (size < min) { \
Error::the().add(::format("wrong number of arguments: {}, {}", name, size)); \
blaze::Error::the().add(::format("wrong number of arguments: {}, {}", name, size)); \
return result; \
}
@ -72,7 +72,7 @@
#define CHECK_ARG_COUNT_BETWEEN_IMPL(name, size, min, max, result) \
if (size < min || size > max) { \
Error::the().add(::format("wrong number of arguments: {}, {}", name, size)); \
blaze::Error::the().add(::format("wrong number of arguments: {}, {}", name, size)); \
return result; \
}
@ -90,7 +90,7 @@
#define CHECK_ARG_COUNT_EVEN_IMPL(name, size, result) \
if (size % 2 != 0) { \
Error::the().add(::format("wrong number of arguments: {}, {}", name, size)); \
blaze::Error::the().add(::format("wrong number of arguments: {}, {}", name, size)); \
return result; \
}
@ -108,7 +108,7 @@
#define IS_VALUE_IMPL(type, value, result) \
if (!is<type>(value.get())) { \
Error::the().add(::format("wrong argument type: {}, {}", #type, value)); \
blaze::Error::the().add(::format("wrong argument type: {}, {}", #type, value)); \
return result; \
}

Loading…
Cancel
Save