felixguendling / cista Goto Github PK
View Code? Open in Web Editor NEWCista is a simple, high-performance, zero-copy C++ serialization & reflection library.
Home Page: https://cista.rocks
License: MIT License
Cista is a simple, high-performance, zero-copy C++ serialization & reflection library.
Home Page: https://cista.rocks
License: MIT License
The following program
#include <iostream>
#include "cista.h"
struct a {
static int x;
int z;
CISTA_PRINTABLE(a)
};
struct b : public a {
int y;
CISTA_PRINTABLE(b)
};
int main() {
b instance;
std::cout << instance;
// "{1, 2, 100, hello}"
}
int a::x = 42;
yields the following error for me:
~/Downloads $ clang++-9 -std=c++2a bah.cc -o bah 16:27:20
In file included from bah.cc:2:
./cista.h:2149:11: error: cannot decompose class type 'b': both it and its base class 'a' have non-static data members
auto& [p1, p2] = t;
^
./cista.h:3734:58: note: in instantiation of function template specialization 'cista::to_tuple<const b>' requested here
std::apply([&](auto&&... args) { (fn(args), ...); }, to_tuple(t));
^
bah.cc:12:5: note: in instantiation of function template specialization 'cista::for_each_field<const b, (lambda at bah.cc:12:5)>' requested here
CISTA_PRINTABLE(b)
^
./cista.h:6381:14: note: expanded from macro 'CISTA_PRINTABLE'
::cista::for_each_field(o, [&](auto&& f) { \
^
1 error generated.
I would like to use cista in a project where there is a lot of inheritance and static members, so this is a problem. I don't know enough about [] binding and templating to know if there is a way to work around this, or if it's a more fundamental limitation.
Hi, the library looks great but it seems there is no support for unions. Unions are needed for polymorphism.
I tried
struct my_struct { // Define your struct.
int a_{0};
union inner {
int b_{0};
char d_;
} j;
};
and the main error using VS2019 is C2672: 'arity': no matching overloaded function found
and using latest GCC is cista.h:1290:31: error: no matching function for call to ‘arity(const main()::my_struct::inner&)’.
Maybe std::variant would help in this case instead of plain union.
Hi,
I have heavily tested Björn Fahller's arity approach used here and I found that (...)MAKE_ARITY_FUNC(1) will fail for simple one-field PODs such as: struct Field1 { int number1; };
It's because is_paren_constructible would be true in such a case (count = 1), here:
cista/include/cista/reflection/arity.h
Line 62 in e25935a
IMHO (...)MAKE_ARITY_FUNC(1) should be considered as a special case, e.g. without is_paren_constructible at all or as for a sake of template is_paren_constructible<T, count>() (with negation removed).
Have not found any example about how to write a custom serialize funtion, so i try myself.
Here is my struct:
struct vec3 {
float x, y, z;
};
struct mat4 {
float d[16];
};
struct Vertex {
vec3 position;
vec3 normal;
};
struct Mesh {
cista::raw::vector<mat4> transforms;
cista::raw::vector<Vertex> vertices;
};
using Meshes = cista::raw::vector<Mesh>;
And my serialize funtions:
template <typename Ctx>
void serialize(Ctx& c, Mesh const* mesh, cista::offset_t const pos) {
for(auto const& t : mesh->transforms) {
c.write(pos, t);
}
for(auto const& v : mesh->vertices) {
c.write(pos, v);
}
}
template <typename Ctx>
void serialize(Ctx& c, Meshes const* meshes, cista::offset_t const pos) {
for(auto const& mesh : *meshes) {
c.write(pos, mesh);
}
}
The crash error:
Unhandled exception at 0x772E35D2 in cista-example.exe: Microsoft C++ exception: std::runtime_error at memory location 0x00BEFAB8.
Hi
the current release of version is 0.4, which is behand master too much
I'm trying to build release from master branch
mkdir build;
cd build
cmake3 -f CMakeLists.txt -DCMAKE_CXX_COMPILER=/opt/scylladb/bin/g++ ../
make
configure is ok,but nothing can be found at dir build or subdir
Hello.
I have ancient C project with structs like this:
typedef struct {
uint8_t *bits;
uint8_t type;
int16_t w;
int16_t h;
} Bitmap;
typedef struct {
int16_t x1;
int16_t y1;
int16_t x2;
int16_t y2;
} Rect;
typedef struct {
Bitmap bm;
union {
Rect updateArea;
Rect anchorArea;
};
int32_t palette;
} Frame;
I have serialized binary files which I need to read, but they are produced by a 32-bit tool where pointers equals 4 bytes. So I need to correctly initialize a 32-bit pointer from the Bitmap
struct which points to binary data that follows directly after a serialized struct (like ptr = *Frame + 1
). How can I implement this with Cista++?
Seems like to_vec
is the go-to function for converting things into the data::vector
type. However, to_vec
only works with pointer types. E.g. can't convert std::vector<double>
to data::vector<double>
. Am I misunderstanding how it should be used?
Hi!
I know, I know... how this issue summary sounds :) so let's go to an example.
I have cista representation of JSON structure like this (cista::mode
is NONE
default):
namespace CISTA = cista::offset;
using Null = std::monostate;
struct MetaArray;
struct MetaObject;
using MetaValue = CISTA::variant
<
Null,
CISTA::string,
std::int64_t,
std::uint64_t,
double,
bool,
CISTA::unique_ptr<MetaArray>,
CISTA::unique_ptr<MetaObject>
>;
struct MetaArray : public CISTA::vector<MetaValue> {};
struct MetaObject : public CISTA::hash_map<CISTA::string, MetaValue> {};
Building it works (starting at MetaObject level) with no problem -> after this silly change #96
Serialization of MetaObject or directly MetaValue breaks at:
cista/include/cista/reflection/to_tuple.h
Line 472 in 23875ef
Same for both std::vector<>/void cista::serialize(...)
approaches
i'm trying build against MSVC Win32. Does this assertion means only 64bit is supported?
deserialize(CharT *in, CharT *out)
only works with const char*
in CAST mode. If I try setting the mode to non-CAST, deserialization_context
requires the input to be char*
and check
only works with uint8_t
.
Is it possible to make the API work with both const char*
and const uint8_t*
in all modes?
This is concerning https://github.com/felixguendling/cista/wiki/Installation-and-Usage#basic-usage
Specifically "more types such as map/set/etc. may follow"
Does this mean that structs containing cista::offset::hash_map<T, T2>
aren't able to be serialized automatically? I'm also wondering if this statement is up to date.
Hi,
I have investigated arity calculations more deeply lately and I think I found much a simpler and elegant way than one implemented here as Björn Fahller idea.
It ts this one: "aggregate arity" by Anatoliy V. Tomilov, @tomilov.
Of course it still does not handles arity for non-aggregates as struct-binding will do, but this is known "issue" - goes the same for Björn's implementation.
It is fully SFINAE-automatic (no macros) with std::declval's from non-static wildcard, and additionally - most important - it could be quite easily extended by relatively simple logic for log_time-like arity calculations, you could find examples/ideas of this in the links listed in my gist attached below.
So, here is my current approach: "ChemiaAion arity"
You could also find a little refactored Björn's implementation there for a reference.
I think you should consider this alternative approach for compile-time speed optimizations.
a default "version" (single-byte 0) added before each struct would make it easier to evolve the schema.
I'm using devtoolset-8 on centos7 to get a higher verison of gcc without influencing the system gcc。
when compiler the master, I get on error as blew
thirdparty/cista/aligned_alloc.h:28:9: error: ‘aligned_alloc’ is not a member of ‘std’
(std::aligned_alloc(
The reason is that libc is to old from the answer compiler-cant-find-aligned-alloc-function
#if __cplusplus >= 201703L && defined(_GLIBCXX_HAVE_ALIGNED_ALLOC)
using ::aligned_alloc;
#endif
so I change to code to fix this error
+#elif defined(_GLIBCXX_HAVE_ALIGNED_ALLOC)
+ #include <memory>
+ #define CISTA_ALIGNED_ALLOC(alignment, size) \
+ (std::aligned_alloc( \
+ cista::next_power_of_two((alignment)), \
+ cista::to_next_multiple((size), cista::next_power_of_two((alignment)))))
#else
-#include <memory>
-#define CISTA_ALIGNED_ALLOC(alignment, size) \
- (std::aligned_alloc( \
- cista::next_power_of_two((alignment)), \
- cista::to_next_multiple((size), cista::next_power_of_two((alignment)))))
+ #define CISTA_ALIGNED_ALLOC(alignment, size) (std::malloc((size)))
#define CISTA_ALIGNED_FREE(ptr) std::free((ptr))
I my project I use one 3d-party closed-source library which I can't modify. That library uses some rather 'fat' C structures which also contain C-arrays. I'd like to serializes/deserialize these structures, but it looks like cista
doesn't support C-arrays. Are there any plans to make such serialization possible? Or is it currently unsolvable task? Also any advise on how to deal with such situation will be highly appreciated.
Are the minimum supported compiler versions documented anywhere?
Hi Felix!
It's been a while since my last interaction with Cista.... so many new features since, my congrats!
To the point... :)
I have switched lately my project to the VS "/std:c++latest" and "/std:c++20" (both: 2019 and 2022 preview) and since that I noticed that this serialize(...)
usage:
cista/include/cista/serialization.h
Lines 324 to 326 in 23875ef
I know, I know that Cista is C++17 project... but since everything else just works(!) and only this one(!) particular error occurs (even during clean single-header build/tests) I though it is worth mentioning here.
FYI: I did all the preliminary use-case analysis, all of them - even simple tryout of cista::variant serialization leads to "this".
I will investigate it further on my own (right now)... but I'm silently counting on your help here - even it is outside the target (C++17).
Not sure what's exactly causing the issue, but once I nest templates deep enough the following happens upon trying to call the cista::offset::to_vec(std::vector<double>)
macro:
my.cpp: In function `cista::basic_vector<double, cista::offset_ptr<double, void>, false, unsigned int>::basic_vector()':
/usr/local/cista/include/cista/containers/vector.h:21: undefined reference to `cista::offset_ptr<double, void>::offset_ptr(decltype(nullptr))'
my.cpp: In function `cista::basic_vector<double, cista::offset_ptr<double, void>, false, unsigned int>::basic_vector(cista::basic_vector<double, cista::offset_ptr<double, void>, false, unsigned int> const&)':
/usr/local/cista/include/cista/containers/vector.h:47: undefined reference to `cista::offset_ptr<double, void>::offset_ptr(decltype(nullptr))'
collect2: error: ld returned 1 exit status
Error disappears once I create and call to_vec
function instead of the to_vec
macro:
inline auto to_vec(const std::vector<double> &vs) {
message::data::vector<double> v;
v.reserve(std::size(vs));
std::copy(std::cbegin(vs), std::cend(vs), std::back_inserter(v));
return v;
}
If I make the above function a template, i.e. to_vec<double>(std::vector)
, the link error comes back.
Hi!
During serialization, the size of a type provided is calculated by sizeof(value)
, here:
cista/include/cista/serialization.h
Lines 194 to 196 in 707ef83
This is too early IMO to calculate size and alignment when working with custom type.
For example, let's consider these structs:
struct Simple { std::vector<int> data; } simple;
template <typename Ctx>
void serialize(Ctx& c, Simple const* el, offset_t const pos) { c.write(pos, el->data[0]); }
struct Complex { Simple simple1; Simple simple2; Simple simple3; } complex;
template <typename Ctx>
void serialize(Ctx& c, Complex const* el, offset_t const pos) { c.write(pos, (int)42); }
When serialized, they will create 0x20 and 0x60 bytes respectiviely (std::vector from MVSC 2017 15.9.0) for cista::byte_buf
as a result of sizeof(Simple) and sizeof(Complex) - this cannot be easily overloaded in custom serialization since Context is already given (alocated) and it could only grow.
cista::to_tuple
is giving this error
/root/workdir/Include/ThirdParty/cista/cista.h:2005:11: error: 13 names provided for structured binding
2005 | auto& [p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13] = t;
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/root/workdir/Include/ThirdParty/cista/cista.h:2005:11: note: while ‘const al’ decomposes into 4 elements
with this struct:
struct al {
float a;
alignas(8) char b;
char bb;
char arr[10];
};
Note: Struct was taken from here (I am trying to implement offsetof
for all members in a struct).
P.s There are other cases that this does not work work with (base structs, structs with #pragma (pack, N)
etc. with similar problems, do you want bug reports on those?
On windows with msys(mingw64) very strange behavior occurs. Cista tries include linux headers on windows and file.h uses linux implementation. I replace _MSC_VER with _WIN32 and and changed the compile conditions a little in many places and cista started to work well. I'm not sure that I did well, but it works.
Could it be possible to add support for more basic string types like std::wstring, std::u16string, std::u32string.
Pretty much it, i would add this my self but im confused as to how the string gets turned to bytes.
Is it safe to just add more genric_string defines for std::u16string?
i have a struct Group
like this:
struct vec3 {
float x, y, z;
};
struct mat4 {
float d[16];
};
struct Vertex {
vec3 position;
vec3 normal;
};
struct Mesh {
cista::raw::vector<mat4> transforms;
cista::raw::vector<Vertex> vertices;
};
using Meshes = cista::raw::vector<Mesh>;
struct Staging {
int stepIndex;
cista::raw::vector<float> distances;
cista::raw::vector<vec3> translations;
cista::raw::vector<vec3> rotations;
};
using Stagings = cista::raw::vector<Staging>;
struct Group {
Meshes meshes;
Stagings stagings;
}
have not found any similar example.
I'm trying to use cista for a protocol with messages (structures) having between 8 and 88 bytes. I used cista::offset::vector<cista::variant<msg1, msg2, etc.>>.
Having a vector containing 10 messages of 8 bytes, what would be the memory used? I guess the serialized buffer will have approximately the same size.
Hi Felix,
I want to serialize an ordered map. Because the library doesn't provide such container I would use std::map.
using ordered_map = std::map<std::uint32_t, cista::offset::hash_set<int>>;
The documentation doesn't cover such topic and I'm asking:
I think this serialization and deserialization of needs raw mode instead of offset mode (and offset mode just for mapped value).
How the custom serialization and deseriation functions would look like?
I would be a good point in documentation the custom serialization and deserialization of a std::map.
Is it possible to include such map in a structure serializing and deserializing the entire structure? Eg.
struct my_data
{
ordered_map map;
cista::offset::vector<int> array;
};
Regards
Flaviu
Hi,
As I mentioned in #13 we should also handle type ref decay for std::reference_wrapper<>
;
This thing will pass a reference under the radar of std::remove_reference_t<>
;
Please take a look on my gist for related test snippets: Type Reference Decay Tryouts
Please improve the decay_t
utility by std::reference_wrapper<>
dedicated decay layer, e.g. something like DecayReferenceWrapper
from my gist.
Hey,
I am trying to reflect a packed struct but unfortunately that does not seem to work.
Minimal example:
#include <cista/reflection/for_each_field.h>
#include <cista/reflection/to_tuple.h>
#include <iostream>
struct Test {
int a;
int b;
int c;
} __attribute__((packed));
int main() {
Test test;
test.a = 3;
test.b = 4;
test.c = 5;
cista::for_each_field(test, [&](auto&& m) { std::cout << m << std::endl; });
}
The error is:
...
error: cannot bind packed field 'p1' to 'int&'
...
So the underlying issue seems to be that it is not possible to bind a member of a packed struct to a reference.
If i remove the attribute((packed)) it works just fine.
I guess there is not much we can do about it?
The following code fails:
namespace data = cista::offset;
data::vector<uint32_t> a;
data::vector<uint32_t> b;
b =a;
Error:
cannot increment value of type 'cista::offset_ptr'
for (; copy_source != end_it; ++copy_source, ++copy_target) {
One reason is that operator++ are not defined for offset pointers.
I try to run this simple code and I get exception
'std::runtime_error': what(): open file mode not supported
from file "cista/targets/file.h" line 31
verify(read || write, "open file mode not supported");
I use Windows with msys2(mingw64).
namespace data = cista::offset;
constexpr auto const MODE = cista::mode::WITH_VERSION | cista::mode::WITH_INTEGRITY;
struct pos {
int x, y;
};
using vec = data::vector<pos>;
{
vec positions{{1, 2}, {3, 4}, {5, 6}, {7, 8}};
cista::buf mmap{cista::mmap{"data"}};
cista::serialize<MODE>(mmap, positions);
}
auto b = cista::mmap("data", cista::mmap::protection::MODIFY);
auto positions = cista::deserialize<vec, MODE>(b);
positions->push_back({5, 5});
for(auto pos : *positions) {
std::cout << pos.x << " " << pos.y << std::endl;
}
And question. I need load data from disk and modify it, but I don't need to sync data always with disk.
Should I serialize data from disk, copy it to memory and, after changing it, serialize it back?
Or should I just use mmap::modify? I do not fully understand how much mmap costs and what is more efficient"
The last release (0.4) dates back from 2 Jan 2019 and many useful commits have happened since.
Do you have a rough estimate of when you might make a new release ?
And maybe what do you think is missing that you want for the next release to happen ?
Thanks for this very nice serialization library.
std::variant<
unique_ptr<T> /* aus T const& angelegt und kopiert */,
T const* /* pointer aus bereits alignedtem speicher gespeichert */,
aligned_buf /* unaligned pointer musste kopiert werden */
>
Hi,
Could you please consider making the constexpr serialized_size()
as a pure non-constexpr inlined static func with default void* = nullptr
argument?
This will add much more more flexibility IMHO for advanced customizations, with relatively (if any) low cost from cista point of view, AFIK this should/would be pretty simple inlined...
That is to say, it will allow to auto custom = reinterpret_cast<CustomType*>(proposed_void_arg);
and then some direct fancy CustomType
size calculations.
if im defined the similar data structures in C#;
How could be do deserialize in C# for the Data serialized by C++.
Is there a vcpkg port?
When I tried to compile a win32 project I got bit_counting.h(94,35): error C3861: _mm_popcnt_u64: identifier not found
This is because win32 doesn't support mm_popcntu64 only mm_popcntu32
Clang compiler (windows) doesn't support booth _mm_popcnt_u64 and _mm_popcnt_u32.
I suppose this can be replaced with __popcnt which is supported by MSVC and Сlang
In my application I have several big data structures, that I want to dump to the disk, and I can compute size of data in compile time. So Im using cista::array
, but seem like there is a bug and Im receiving the invalid address error. Ive attached the example in the hastebin
The error Ive got look like this
* thread #1, name = 'a.out', stop reason = signal SIGSEGV: invalid address (fault address: 0x7ffffdda5d70)
frame #0: 0x00005555555578a0 a.out`unsigned long cista::type_hash<cista_serializator>() at cista.h:4482:8
4479
4480 template <typename T>
4481 hash_t type_hash() {
-> 4482 auto done = std::map<hash_t, unsigned>{};
4483 return type_hash(T{}, BASE_HASH, done);
4484 }
4485
Process 61576 launched: 'a.out' (x86_64)
(lldb) bt
* thread #1, name = 'a.out', stop reason = signal SIGSEGV: invalid address (fault address: 0x7ffffdda5d70)
* frame #0: 0x00005555555578a0 a.out`unsigned long cista::type_hash<cista_serializator>() at cista.h:4482:8
frame #1: 0x0000555555557242 a.out`void cista::serialize<(cista::mode)6, cista::buf<std::vector<unsigned char, std::allocator<unsigned char> > >, cista_serializator>(t=0x00007fffffffe480, value=0x00007ffff582d010) at cista.h:4814:40
frame #2: 0x0000555555556f31 a.out`std::vector<unsigned char, std::allocator<unsigned char> > cista::serialize<(el=0x00007ffff582d010)6, cista_serializator>(cista_serializator&) at cista.h:4845:18
frame #3: 0x0000555555556401 a.out`main(argc=1, argv=0x00007fffffffe608) at main.cpp:41:45
frame #4: 0x00007ffff7ab2152 libc.so.6`__libc_start_main + 242
frame #5: 0x00005555555562ae a.out`_start + 46
OS: Linux x86_64, compiler: gcc version 10.2.0 (GCC), compile command: g++ -std=c++17 -I. -g main.cpp
, Ive tried cista::offset
and cista::raw
, but no luck
Please take a look on this example: https://wandbox.org/permlink/l2iEAmTpiCWFtLb6
Works like a charm, i.e.: CISTA::vector<CISTA::ptr<ElementTest>> paths_
pointers are perfectly rebuild during deserialization.
No issue...
Exactly same stuff under latest VS 17.2.6 with all features beyond C++20 enabled gives me two things:
ElementTest
- whereas wandbox not;ElementTest
, paths_ still points to memory before serialization;I am still investigating this...
One more thing here - on return it should be called cista::index_of_type<T, Ts...>()
<- missing "()"
cista/include/cista/containers/variant.h
Lines 402 to 408 in da8da3a
Originally posted by @ChemistAion in #98 (comment)
Hello
First of all Cista is great, good work, you have my gratitude
I have a small dumb question. Im curious about the compatibility of the data produced by Cista. Is there any known limitations of being used in different environment?
I've tried using the buf
target as a mutable buffer which would store Cista-serialized data before writing to a binary file log. Works great, except I need to access the curr_offset_
member to know the size of data serialized. I also need to reset the buffer after data has been flushed to file which means setting curr_offset_ = 0
.
Given that buf
is a struct - is this by design or should an offset()
and reset()
methods be added?
Hi,
I noticed that all types decays are formed as: std::remove_reference_t<std::remove_const_t<>>
;
This seems to be enough for almost all current use cases, besides sizeof(std::declval<>)
:
std::is_scalar_v<>
is happy with cv qualifiers, i.e.: it gives the same answer for all cv combinations;
std::is_pointer_v<>
removes cv qualifiers, so it is happy;
std::alignment_of_v<>
is happy;
std::numeric_limits<>
are happy;
sizeof(std::declval<>)
I would be somehow careful here, since returned std::add_rvalue_reference<>
could be problematic (impossible types) when used with const/volatile qualifiers, details: LWG2101;
I would recommend to strength all types decays as std::remove_reference_t<std::remove_cv_t<>>
;
Not sure if this can be solved generically, but would be nice if CISTA_PRINTABLE
worked for e.g. offset::vector<MyEnum>
by defaulting to the underlying enum type.
build with cmake3.6 will get error
Make Error at tools/doctest/CMakeLists.txt:5 (target_compile_features):
target_compile_features specified unknown feature "cxx_std_11" for target
"cista-doctest".
CMake Error at tools/uniter/CMakeLists.txt:4 (target_compile_features):
target_compile_features specified unknown feature "cxx_std_17" for target
"uniter".
CMake Error at CMakeLists.txt:90 (target_compile_features):
target_compile_features specified unknown feature "cxx_std_17" for target
"cista-test-single-header".
-- Configuring incomplete, errors occurred!
It looks like cxx_std_17 was added in CMake 3.8:
https://cmake.org/cmake/help/v3.8/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.html
SO pls change from 3.5 to 3.8
cmake_minimum_required(VERSION 3.8)
first off, cista rocks indeed!
While skimming through the code I noticed xxhash usage. I suggest using wyhash instead as it performs better.
I have this little fellow here:
using Variant = CISTA::variant
<
bool,
std::int64_t
>;
Variant test{ true };
auto result = cista::get_if<bool>(test);
...and I am getting (on VS2019/VS2022prev, both C++20):
"Error C2563 mismatch in formal parameter list"
"Error C2568 '==': unable to resolve function overload"
on:
cista/include/cista/containers/variant.h
Line 380 in 23875ef
I know that I could address bool
by its index in Variant
- namely 0
, but how to make it happen with Type directly?
I am trying to make this through cista::get_if
implementations... test-case "variant_test.cc" helps me not.
Guys I got some trouble when serialize a struct has base, I simplified code into following
struct Base {};
struct Derive:Base {
int field;
};
// ......
// Derive d = {{}, 0};
std::vector<uint8_t> out = cista::serialize<MODE, Derive>(d);
};
And the compiler gave error like
/**/cista-0.6/include/cista/reflection/to_tuple.h:230:11: error: type 'const Derive' decomposes into 1 elements, but 2 names were provided
auto& [p1, p2] = t;
^
Obviously, the prolblem was caused because Derive d
has to be init like {{}, 0}
rather than {0}
, so the arity()
gives the number of binging arguments is 2.
So, is there any way to solve it or we just can not use cista to serialize struct with inheritance?
Support to deserialize data deserialize data on big-endian systems that was serialized on little endian systems and vice versa.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.