Skip to content

Commit

Permalink
upgrade to v1.0.1
Browse files Browse the repository at this point in the history
  • Loading branch information
Clemapfel authored Dec 6, 2023
2 parents a3d6635 + d9f37f0 commit 537d423
Show file tree
Hide file tree
Showing 10 changed files with 215 additions and 80 deletions.
80 changes: 66 additions & 14 deletions .src/array.inl
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ namespace jluna
}

template<is_boxable V, uint64_t R>
auto Array<V, R>::operator[](uint64_t i)
auto Array<V, R>::linear_index(uint64_t i)
{
if (i >= get_n_elements())
{
Expand All @@ -138,7 +138,13 @@ namespace jluna
}

template<is_boxable V, uint64_t R>
Vector<V> Array<V, R>::operator[](const std::vector<uint64_t>& range) const
auto Array<V, R>::operator[](uint64_t i)
{
return linear_index(i);
}

template<is_boxable V, uint64_t R>
Vector<V> Array<V, R>::at(const std::vector<uint64_t>& range) const
{
gc_pause;
auto* out = unsafe::new_array((unsafe::Value*) as_julia_type<V>::type(), range.size());
Expand All @@ -152,34 +158,54 @@ namespace jluna
}

template<is_boxable V, uint64_t R>
Vector<V> Array<V, R>::operator[](const GeneratorExpression& gen) const
Vector<V> Array<V, R>::at(const GeneratorExpression& gen) const
{
gc_pause;
auto res = Vector<V>();
res.reserve(gen.size());

for (auto it : gen)
res.push_back(this->operator[](unbox<uint64_t>(it)));
res.push_back(this->at(unbox<uint64_t>(it)));

gc_unpause;
return res;
}

template<is_boxable V, uint64_t R>
template<is_boxable T>
Vector<V> Array<V, R>::operator[](std::initializer_list<T>&& list) const
Vector<V> Array<V, R>::at(std::initializer_list<T>&& list) const
{
std::vector<uint64_t> index;
index.reserve(list.size());
for (auto& e : list)
index.push_back(e);

return operator[](index);
return at(index);
}


template<is_boxable V, uint64_t R>
Vector<V> Array<V, R>::operator[](const std::vector<uint64_t>& range) const
{
return this->at(range);
}

template<is_boxable V, uint64_t R>
Vector<V> Array<V, R>::operator[](const GeneratorExpression& gen) const
{
return this->at(gen);
}

template<is_boxable V, uint64_t R>
template<is_boxable T>
Vector<V> Array<V, R>::operator[](std::initializer_list<T>&& list) const
{
return this->at(std::forward<std::initializer_list<T>&&>(list));
}

template<is_boxable V, uint64_t R>
template<is_unboxable T>
T Array<V, R>::operator[](uint64_t i) const
T Array<V, R>::linear_index(uint64_t i) const
{
if (i >= get_n_elements())
{
Expand All @@ -192,7 +218,14 @@ namespace jluna
}

template<is_boxable V, uint64_t R>
template<is_unboxable T, typename... Args, std::enable_if_t<sizeof...(Args) == R and (std::is_integral_v<Args> and ...), bool>>
template<is_unboxable T>
T Array<V, R>::operator[](uint64_t i) const
{
return linear_index(i);
}

template<is_boxable V, uint64_t R>
template<is_unboxable T, typename... Args, std::enable_if_t<R >= 2 and sizeof...(Args) == R and (std::is_integral_v<Args> and ...), bool>>
T Array<V, R>::at(Args... in) const
{
{
Expand Down Expand Up @@ -221,7 +254,7 @@ namespace jluna
#endif

template<is_boxable V, uint64_t R>
template<typename... Args, std::enable_if_t<sizeof...(Args) == R and (std::is_integral_v<Args> and ...), bool>>
template<typename... Args, std::enable_if_t<R >= 2 and sizeof...(Args) == R and (std::is_integral_v<Args> and ...), bool>>
auto Array<V, R>::at(Args... in)
{
{
Expand All @@ -240,7 +273,26 @@ namespace jluna
mul *= dim;
}

return operator[](index);
return linear_index(index);
}

template<is_boxable V, uint64_t R>
template<typename... Args, std::enable_if_t<sizeof...(Args) == 1 and (std::is_integral_v<Args> and ...), bool>>
auto Array<V, R>::at(Args... in)
{
auto index = (in, ...);
return linear_index(index);
}

/// @brief linear indexing
/// @param n: singular index
/// @returns unboxed value
template<is_boxable V, uint64_t R>
template<is_unboxable T, typename... Args, std::enable_if_t<sizeof...(Args) == 1 and (std::is_integral_v<Args> and ...), bool>>
T Array<V, R>::at(Args... in) const
{
auto index = (in, ...);
return linear_index<T>(index);
}

#ifdef _MSC_VER
Expand All @@ -257,7 +309,7 @@ namespace jluna
template<is_boxable V, uint64_t R>
auto Array<V, R>::front()
{
return operator[](0);
return linear_index(0);
}

template<is_boxable V, uint64_t R>
Expand Down Expand Up @@ -288,20 +340,20 @@ namespace jluna
template<is_unboxable T>
T Array<V, R>::front() const
{
return static_cast<T>(operator[](0));
return static_cast<T>(linear_index(0));
}

template<is_boxable V, uint64_t R>
auto Array<V, R>::back()
{
return operator[](get_n_elements() - 1);
return linear_index(get_n_elements() - 1);
}

template<is_boxable V, uint64_t R>
template<is_unboxable T>
T Array<V, R>::back() const
{
return operator[]<T>(get_n_elements() - 1);
return linear_index<T>(get_n_elements() - 1);
}

template<is_boxable V, uint64_t R>
Expand Down
8 changes: 7 additions & 1 deletion .src/box.inl
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,13 @@ namespace jluna
jl_arrayset(args_t, jl_typeof(jl_arrayref(args_v, i)), i);

auto tuple_t = jl_apply_tuple_type_v((jl_value_t**) args_t->data, args_t->length);
auto* out = jl_new_structv(tuple_t, (jl_value_t**) args_v->data, args_v->length);

#if JULIA_VERSION_MAJOR >= 2 or JULIA_VERSION_MINOR >= 10
auto* out = jl_new_structv((jl_datatype_t*) tuple_t, (jl_value_t**) args_v->data, args_v->length);
#else
auto* out = jl_new_structv(tuple_t, (jl_value_t**) args_v->data, args_v->length);
#endif

gc_unpause;
return out;
}
Expand Down
3 changes: 1 addition & 2 deletions .src/safe_utilities.inl
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,7 @@ namespace jluna

jl_eval_string(R"(
begin
local version = tryparse(Float32, SubString(string(VERSION), 1, 3))
if (version < 1.7)
if (isless(VERSION, v"1.7"))
local message = "jluna requires julia v1.7.0 or higher, but v" * string(VERSION) * " was detected. Please download the latest julia release at https://julialang.org/downloads/#current_stable_release, set JULIA_BINDIR accordingly, then recompile jluna using cmake. For more information, visit https://github.com/Clemapfel/jluna/blob/master/README.md#troubleshooting"
throw(AssertionError(message))
end
Expand Down
12 changes: 11 additions & 1 deletion .src/type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,20 @@

namespace jluna
{
namespace detail
{
inline bool is_union_empty(jl_datatype_t* type)
{
static auto* propertynames = jl_get_function(jl_main_module, "propertynames");
static auto* sizeof_f = jl_get_function(jl_main_module, "sizeof");
return jl_unbox_int64(jl_call1(sizeof_f, jl_call1(propertynames, (jl_value_t*) type))) == 0;
}
}

Type::Type() = default;

Type::Type(jl_datatype_t* value)
: Proxy((unsafe::Value*) value, (value->name == nullptr ? jl_symbol("Union{}") : value->name->name))
: Proxy((unsafe::Value*) value, (detail::is_union_empty(value) ? jl_symbol("Union{}") : value->name->name))
{}

Type::Type(Proxy* owner)
Expand Down
16 changes: 14 additions & 2 deletions .src/unsafe_utilities.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,13 @@ namespace jluna::unsafe
types.at(i) = (unsafe::Value*) jl_int64_type;

auto* tuple_type = jl_apply_tuple_type_v(types.data(), types.size());
auto* tuple = jl_new_struct(tuple_type, jl_box_int64(static_cast<Int64>(one_d)));

#if JULIA_VERSION_MAJOR >= 2 or JULIA_VERSION_MINOR >= 10
auto* tuple = jl_new_struct((jl_datatype_t*) tuple_type, jl_box_int64(static_cast<Int64>(one_d)));
#else
auto* tuple = jl_new_struct(tuple_type, jl_box_int64(static_cast<Int64>(one_d)));
#endif

auto* res = jl_reshape_array(jl_apply_array_type(unsafe::call(array_value_t, array), 1), array, tuple);
override_array(array, res);
gc_unpause;
Expand All @@ -219,7 +225,13 @@ namespace jluna::unsafe
types.at(i) = (unsafe::Value*) jl_int64_type;

auto* tuple_type = jl_apply_tuple_type_v(types.data(), types.size());
auto* tuple = jl_new_struct(tuple_type, jl_box_int64(static_cast<Int64>(one_d)), jl_box_int64(static_cast<Int64>(two_d)));

#if JULIA_VERSION_MAJOR >= 2 or JULIA_VERSION_MINOR >= 10
auto* tuple = jl_new_struct((jl_datatype_t*) tuple_type, jl_box_int64(static_cast<Int64>(one_d)), jl_box_int64(static_cast<Int64>(two_d)));
#else
auto* tuple = jl_new_struct(tuple_type, jl_box_int64(static_cast<Int64>(one_d)), jl_box_int64(static_cast<Int64>(two_d)));
#endif

auto* res = jl_reshape_array(jl_apply_array_type(unsafe::call(array_value_t, array), 2), array, tuple);
override_array(array, res);
gc_unpause;
Expand Down
23 changes: 20 additions & 3 deletions .src/unsafe_utilities.inl
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,13 @@ namespace jluna::unsafe

return jl_apply_tuple_type_v(types.data(), types.size());
}();
auto* tuple = jl_new_struct(tuple_type, jl_box_uint64(size_per_dimension)...);

#if JULIA_VERSION_MAJOR >= 2 or JULIA_VERSION_MINOR >= 10
auto* tuple = jl_new_struct((jl_datatype_t*) tuple_type, jl_box_uint64(size_per_dimension)...);
#else
auto* tuple = jl_new_struct(tuple_type, jl_box_uint64(size_per_dimension)...);
#endif

auto* res = jl_new_array(jl_apply_array_type(value_type, sizeof...(Dims)), tuple);
jl_gc_enable(before);
return res;
Expand All @@ -127,7 +133,13 @@ namespace jluna::unsafe

return jl_apply_tuple_type_v(types.data(), types.size());
}();
auto* tuple = jl_new_struct(tuple_type, jl_box_uint64(size_per_dimension)...);

#if JULIA_VERSION_MAJOR >= 2 or JULIA_VERSION_MINOR >= 10
auto* tuple = jl_new_struct((jl_datatype_t*) tuple_type, jl_box_uint64(size_per_dimension)...);
#else
auto* tuple = jl_new_struct(tuple_type, jl_box_uint64(size_per_dimension)...);
#endif

auto* res = jl_ptr_to_array(jl_apply_array_type(value_type, sizeof...(Dims)), data, tuple, 0);
jl_gc_enable(before);
return res;
Expand All @@ -148,7 +160,12 @@ namespace jluna::unsafe

static jl_function_t* get_value_type_of_array = get_function("jluna"_sym, "get_value_type_of_array"_sym);

auto* tuple = jl_new_struct(tuple_type, jl_box_uint64(size_per_dimension)...);
#if JULIA_VERSION_MAJOR >= 2 or JULIA_VERSION_MINOR >= 10
auto* tuple = jl_new_struct((jl_datatype_t*) tuple_type, jl_box_uint64(size_per_dimension)...);
#else
auto* tuple = jl_new_struct(tuple_type, jl_box_uint64(size_per_dimension)...);
#endif

auto* res = jl_reshape_array(jl_apply_array_type(unsafe::call(get_value_type_of_array, array), sizeof...(Dims)), array, tuple);
override_array(array, res);
jl_gc_enable(before);
Expand Down
12 changes: 6 additions & 6 deletions .test/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ make_usertype_implicitly_convertible(NonJuliaType);

int main()
{
initialize(2);
initialize(2); //, false, "/home/clem/Workspace/jluna/cmake-build-debug/libjluna.so");

Test::initialize();
Test::test("c_adapter found", [](){
Expand Down Expand Up @@ -886,7 +886,7 @@ int main()

auto vec = jluna::Array<Int64, 1>(Main.safe_eval("return collect(Int64(1):100)"), nullptr);

const auto subvec = vec[{12, 19, 99, 2}];
const auto subvec = vec.at({12, 19, 99, 2});

Test::assert_that(subvec.at(0) == 13 and subvec.at(1) == 20 and subvec.at(2) == 100 and subvec.at(3) == 3);
});
Expand All @@ -899,8 +899,7 @@ int main()
arr.at(0) = "string";
}
catch (...)
{
}
{}
});

Test::test("array: front/back", []() {
Expand Down Expand Up @@ -1018,14 +1017,15 @@ int main()
bool thrown = false;
try
{
arr.begin().operator std::vector<std::string>();
arr.begin().operator Module();
}
catch (...)
{
thrown = true;
}

Test::assert_that(thrown);
Test::assert_that(arr.begin().operator std::string() == "1");
Test::assert_that(arr.begin().operator Int64() == 1);
});

Expand All @@ -1043,7 +1043,7 @@ int main()
Test::test("array: comprehension", []() {

auto arr = jluna::Array<Int64, 1>(jl_eval_string("return collect(0:10)"));
auto vec = arr["(i for i in 0:9 if i % 2 == 0)"_gen];
auto vec = arr.at("(i for i in 0:9 if i % 2 == 0)"_gen);

for (auto it : vec)
Test::assert_that(it.operator int() % 2 == 0);
Expand Down
27 changes: 15 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ jluna aims to fully wrap the official Julia C-API, replacing it in projects with
Array<Int64, 2> matrix = Main.safe_eval("return reshape([i for i in 1:(4*4)], 4, 4)");
// supports multi-dimensional indexing (and array comprehension, not shown here)
matrix[0, 2] = 999;
matrix.at(0, 2) = 999;
Main["println"](matrix);
// even has generator expressions!
Expand Down Expand Up @@ -209,23 +209,26 @@ If any step of this does not work for you, please follow the [installation guide

---

## License
## Credits
jluna was designed and written by [Clem Cords](https://github.com/Clemapfel).

The current and all prior releases of jluna are supplied under MIT license, available [here](./LICENSE.txt).
#### March 2022:<br>
+ CMake improvements by [friendlyanon](https://github.com/friendlyanon)

I would like to ask people using this library in commercial or university settings, to disclose their usage of jluna in some small way (for example, at the end of the credits or via a citation) and to make clear the origin of the work (for example by linking this GitHub page).
## Donations

If you would like to cite jluna in your academic publication, you can copy the entry in [CITATION.bib](CITATION.bib) to your [BibTeX](https://www.overleaf.com/learn/latex/Bibliography_management_with_bibtex) bibliography, then use the `\cite{jluna}` command anywhere in your [LaTeX](https://www.latex-project.org/) source code.
Jluna was created with no expectation of compensation and made available for free. Consider donating to reward past work and support the continued development of this library:

Thank you for your consideration,
C.
+ [GitHub Sponsors](https://github.com/sponsors/Clemapfel)
+ [PayPal](https://www.paypal.com/donate/?hosted_button_id=8KWF3JTDF8XL2)

---

## Credits
jluna was designed and written by [Clem Cords](https://github.com/Clemapfel).
## License & Citation

#### March 2022:<br>
+ CMake improvements by [friendlyanon](https://github.com/friendlyanon)
The current and all prior releases of jluna are supplied under MIT license, available [here](./LICENSE.txt).

---
If you would like to cite jluna in your academic publication, you can copy the entry in [CITATION.bib](CITATION.bib) to your [BibTeX](https://www.overleaf.com/learn/latex/Bibliography_management_with_bibtex) bibliography, then use the `\cite{jluna}` command anywhere in your [LaTeX](https://www.latex-project.org/) source code.

Thank you for your consideration,
C.
Loading

0 comments on commit 537d423

Please sign in to comment.