add C++ support
This is so not a good idea but i'll need it for Catch2
This commit is contained in:
parent
f5bb5edcd3
commit
befc18f8ff
9 changed files with 103 additions and 22 deletions
|
@ -6,11 +6,19 @@
|
||||||
#error "Only gcc and clang are supported"
|
#error "Only gcc and clang are supported"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "neo/_error.h"
|
#include "neo/_error.h"
|
||||||
#include "neo/_types.h"
|
#include "neo/_types.h"
|
||||||
#include "neo/_stddef.h"
|
#include "neo/_stddef.h"
|
||||||
#include "neo/_nalloc.h"
|
#include "neo/_nalloc.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}; /* extern "C" */
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This file is part of libneo.
|
* This file is part of libneo.
|
||||||
* Copyright (c) 2021 Fefie <owo@fef.moe>.
|
* Copyright (c) 2021 Fefie <owo@fef.moe>.
|
||||||
|
|
|
@ -2,6 +2,10 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "neo/_types.h"
|
#include "neo/_types.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -46,19 +50,26 @@ void errput(error *err);
|
||||||
* by `err` is an actual error, i.e. it has been `yeet`ed to.
|
* by `err` is an actual error, i.e. it has been `yeet`ed to.
|
||||||
* Resources for the error must be released using `nput`.
|
* Resources for the error must be released using `nput`.
|
||||||
*/
|
*/
|
||||||
#define catch(err) if ((err) != nil && (err)->_number != 0)
|
#define ncatch(err) if ((err) != nil && (err)->_number != 0)
|
||||||
|
#ifndef __cplusplus
|
||||||
|
# define catch(err) ncatch(err)
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the error number.
|
* Get the error number.
|
||||||
* Must only be used within a catch block and before `errput` is called.
|
* Must only be used within a catch block and before `errput` is called.
|
||||||
*/
|
*/
|
||||||
#define errnum(err) ((err)->_number)
|
#define errnum(err) ((err) == nil ? 0 : (err)->_number)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get an optional error message, this may be `nil`
|
* Get an optional error message, this may be `nil`
|
||||||
* Must only be used within a catch block and before `errput` is called.
|
* Must only be used within a catch block and before `errput` is called.
|
||||||
*/
|
*/
|
||||||
#define errmsg(err) ((err)->_message)
|
#define errmsg(err) ((err) == nil ? nil : (err)->_message)
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}; /* extern "C" */
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This file is part of libneo.
|
* This file is part of libneo.
|
||||||
|
|
|
@ -2,6 +2,10 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "neo/_toolchain.h"
|
#include "neo/_toolchain.h"
|
||||||
#include "neo/_types.h"
|
#include "neo/_types.h"
|
||||||
|
|
||||||
|
@ -46,6 +50,10 @@ void *nzalloc(usize size, error *err);
|
||||||
__neo_malloc(nfree, 1)
|
__neo_malloc(nfree, 1)
|
||||||
void *nrealloc(void *ptr, usize newsize, error *err);
|
void *nrealloc(void *ptr, usize newsize, error *err);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}; /* extern "C" */
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This file is part of libneo.
|
* This file is part of libneo.
|
||||||
* Copyright (c) 2021 Fefie <owo@fef.moe>.
|
* Copyright (c) 2021 Fefie <owo@fef.moe>.
|
||||||
|
|
|
@ -2,6 +2,10 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "neo/_types.h"
|
#include "neo/_types.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -47,6 +51,10 @@ int _neo_nput(struct _neo_nref *ref);
|
||||||
*/
|
*/
|
||||||
#define nput(ptr) (_neo_nput( &(ptr)->__neo_nref ))
|
#define nput(ptr) (_neo_nput( &(ptr)->__neo_nref ))
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}; /* extern "C" */
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This file is part of libneo.
|
* This file is part of libneo.
|
||||||
* Copyright (c) 2021 Fefie <owo@fef.moe>.
|
* Copyright (c) 2021 Fefie <owo@fef.moe>.
|
||||||
|
|
|
@ -2,19 +2,23 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "neo/_types.h"
|
#include "neo/_types.h"
|
||||||
|
|
||||||
#define nil ((void *)0)
|
#define nil ((void *)0)
|
||||||
|
|
||||||
#ifndef true
|
#if !defined(__cplusplus) && !defined(true)
|
||||||
#define true ((bool)1)
|
# define true ((bool)1)
|
||||||
#endif
|
#endif
|
||||||
#ifndef false
|
#if !defined(__cplusplus) && !defined(false)
|
||||||
#define false ((bool)0)
|
# define false ((bool)0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef offsetof
|
#ifndef offsetof
|
||||||
#define offsetof(type, member) __builtin_offsetof(type, member)
|
# define offsetof(type, member) __builtin_offsetof(type, member)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -35,6 +39,10 @@
|
||||||
*/
|
*/
|
||||||
#define nlen(thing) ((thing)->__neo_nlen)
|
#define nlen(thing) ((thing)->__neo_nlen)
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}; /* extern "C" */
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This file is part of libneo.
|
* This file is part of libneo.
|
||||||
* Copyright (c) 2021 Fefie <owo@fef.moe>.
|
* Copyright (c) 2021 Fefie <owo@fef.moe>.
|
||||||
|
|
|
@ -18,6 +18,12 @@
|
||||||
#define __neo_fini(fn) \
|
#define __neo_fini(fn) \
|
||||||
__neo_section(.fini_array) static void (*__neo_fini_##fn)(void) = fn
|
__neo_section(.fini_array) static void (*__neo_fini_##fn)(void) = fn
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
# define __restrict
|
||||||
|
#else
|
||||||
|
# define __restrict restrict
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This file is part of libneo.
|
* This file is part of libneo.
|
||||||
* Copyright (c) 2021 Fefie <owo@fef.moe>.
|
* Copyright (c) 2021 Fefie <owo@fef.moe>.
|
||||||
|
|
|
@ -2,6 +2,10 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "neo/_stddef.h"
|
#include "neo/_stddef.h"
|
||||||
|
|
||||||
typedef __INT8_TYPE__ i8;
|
typedef __INT8_TYPE__ i8;
|
||||||
|
@ -25,20 +29,27 @@ typedef float f32;
|
||||||
typedef double f64;
|
typedef double f64;
|
||||||
typedef long double f128;
|
typedef long double f128;
|
||||||
|
|
||||||
typedef _Bool bool;
|
#ifdef __cplusplus
|
||||||
|
/* TODO: This is probably not a good idea */
|
||||||
#define atomic _Atomic
|
#define __neo_atomic_type volatile int
|
||||||
#define complex _Complex
|
#else
|
||||||
|
typedef _Bool bool;
|
||||||
|
# ifdef __STDC_NO_ATOMICS__
|
||||||
|
# error "Atomic types are not implemented"
|
||||||
|
# else
|
||||||
|
# define __neo_atomic_type _Atomic int
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
struct _neo_nref {
|
struct _neo_nref {
|
||||||
void (*_destroy)(void *);
|
void (*_destroy)(void *);
|
||||||
/** byte offset into the struct this is embedded in */
|
/** byte offset into the struct this is embedded in */
|
||||||
usize _offset;
|
usize _offset;
|
||||||
atomic int _count;
|
__neo_atomic_type _count;
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
* A basic reference counter for data structures.
|
* A basic reference counter for data structures.
|
||||||
* Embed this into your data structure as the field `__neo_nref`, initialize
|
* Embed this into your data structure using the `NREF_FIELD` macro, initialize
|
||||||
* it using `nref_init`, and use `nget` and `nput` to increment/decrement the
|
* it using `nref_init`, and use `nget` and `nput` to increment/decrement the
|
||||||
* reference counter.
|
* reference counter.
|
||||||
*/
|
*/
|
||||||
|
@ -61,6 +72,10 @@ struct _neo_error {
|
||||||
};
|
};
|
||||||
typedef struct _neo_error error;
|
typedef struct _neo_error error;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}; /* extern "C" */
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This file is part of libneo.
|
* This file is part of libneo.
|
||||||
* Copyright (c) 2021 Fefie <owo@fef.moe>.
|
* Copyright (c) 2021 Fefie <owo@fef.moe>.
|
||||||
|
|
|
@ -16,6 +16,11 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "neo/_toolchain.h"
|
||||||
#include "neo/_types.h"
|
#include "neo/_types.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -28,7 +33,7 @@
|
||||||
* @returns The number of UTF-8 code points (i.e. number of Unicode characters)
|
* @returns The number of UTF-8 code points (i.e. number of Unicode characters)
|
||||||
* excluding the terminating NUL byte; undefined on error
|
* excluding the terminating NUL byte; undefined on error
|
||||||
*/
|
*/
|
||||||
usize utf8_check(const char *restrict s, error *err);
|
usize utf8_check(const char *__restrict s, error *err);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compute the length of a raw UTF-8 encoded, NUL terminated string.
|
* Compute the length of a raw UTF-8 encoded, NUL terminated string.
|
||||||
|
@ -40,7 +45,7 @@ usize utf8_check(const char *restrict s, error *err);
|
||||||
* @returns: String length as in Unicode code points (not bytes),
|
* @returns: String length as in Unicode code points (not bytes),
|
||||||
* excluding the terminating NUL byte
|
* excluding the terminating NUL byte
|
||||||
*/
|
*/
|
||||||
usize utf8_strlen(const char *restrict s);
|
usize utf8_strlen(const char *__restrict s);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the amount of bytes a Unicode character takes up in UTF-8.
|
* Get the amount of bytes a Unicode character takes up in UTF-8.
|
||||||
|
@ -68,7 +73,7 @@ usize utf8_chrsize(nchar c, error *err);
|
||||||
* @returns The amount of bytes taken up by the character,
|
* @returns The amount of bytes taken up by the character,
|
||||||
* which is always between 1 and 4 except on errors
|
* which is always between 1 and 4 except on errors
|
||||||
*/
|
*/
|
||||||
usize utf8_from_nchr(char *restrict dest, nchar c, error *err);
|
usize utf8_from_nchr(char *__restrict dest, nchar c, error *err);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decode a UTF-8 character and store it in `c`.
|
* Decode a UTF-8 character and store it in `c`.
|
||||||
|
@ -86,7 +91,11 @@ usize utf8_from_nchr(char *restrict dest, nchar c, error *err);
|
||||||
* @returns The amount of bytes the character took up when encoded as UTF-8,
|
* @returns The amount of bytes the character took up when encoded as UTF-8,
|
||||||
* which is always between 1 and 4 except on errors
|
* which is always between 1 and 4 except on errors
|
||||||
*/
|
*/
|
||||||
usize utf8_to_nchr(nchar *c, const char *restrict utf8chr, error *err);
|
usize utf8_to_nchr(nchar *c, const char *__restrict utf8chr, error *err);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}; /* extern "C" */
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This file is part of libneo.
|
* This file is part of libneo.
|
||||||
|
|
16
src/nref.c
16
src/nref.c
|
@ -1,23 +1,31 @@
|
||||||
/** See the end of this file for copyright and license terms. */
|
/** See the end of this file for copyright and license terms. */
|
||||||
|
|
||||||
|
#include <stdatomic.h>
|
||||||
|
|
||||||
#include "neo/_nref.h"
|
#include "neo/_nref.h"
|
||||||
#include "neo/_types.h"
|
#include "neo/_types.h"
|
||||||
|
|
||||||
|
void _neo_nref_init(struct _neo_nref *ref)
|
||||||
|
{
|
||||||
|
atomic_init(&ref->_count, 1);
|
||||||
|
}
|
||||||
|
|
||||||
int _neo_nget(struct _neo_nref *ref)
|
int _neo_nget(struct _neo_nref *ref)
|
||||||
{
|
{
|
||||||
return ++ref->_count;
|
int old = atomic_fetch_add(&ref->_count, 1);
|
||||||
|
return old + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _neo_nput(struct _neo_nref *ref)
|
int _neo_nput(struct _neo_nref *ref)
|
||||||
{
|
{
|
||||||
int count = --ref->_count;
|
int old = atomic_fetch_sub(&ref->_count, 1);
|
||||||
|
|
||||||
if (count == 0) {
|
if (old == 1) {
|
||||||
void *container = (void *)ref - ref->_offset;
|
void *container = (void *)ref - ref->_offset;
|
||||||
ref->_destroy(container);
|
ref->_destroy(container);
|
||||||
}
|
}
|
||||||
|
|
||||||
return count;
|
return old - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in a new issue