Created
August 15, 2018 17:56
-
-
Save dayvonjersen/2730d637c7e5950c43f655035f060183 to your computer and use it in GitHub Desktop.
C++ For Go Programmers: Part 2 - Slices
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdarg.h> | |
#include <stdlib.h> | |
#include <string.h> | |
struct slice { | |
size_t type; | |
int len; | |
int cap; | |
void* arr; | |
}; | |
int len(struct slice* s) { return s->len; } | |
int cap(struct slice* s) { return s->cap; } | |
struct slice* make(size_t type, int len, int cap) { | |
struct slice* s = calloc(1, sizeof(struct slice)); | |
s->arr = calloc(cap, type); | |
s->type = type; | |
s->len = len; | |
s->cap = cap; | |
return s; | |
} | |
struct slice* append(int count, struct slice* s, ...) { | |
va_list args; | |
va_start(args, s); | |
if(s->cap < s->len+count) { | |
s->arr = realloc(s->arr, s->type * s->len+count); | |
s->cap = s->len+count; | |
} | |
int offset = s->len * s->type; | |
for(int j = 0; j < count; j++) { | |
unsigned char* elem = va_arg(args, unsigned char*); | |
for(int i = 0; i < s->type; i++) { | |
*((unsigned char*)s->arr + offset + i + j*s->type) = elem[i]; | |
} | |
} | |
va_end(args); | |
s->len += count; | |
return s; | |
} | |
struct slice* slice(struct slice* s, int start, int end) { | |
int len = end-start; | |
struct slice* s2 = make(s->type, len, len); | |
memcpy(s2->arr, s->arr + start * s->type, len * s->type); | |
s2->len = len; | |
return s2; | |
} | |
int copy(struct slice* dst, struct slice* src) { | |
if(dst->type != src->type) return 0; // should generate an error somehow actually | |
int len = dst->len < src->len ? dst->len : src->len; | |
memcpy(dst->arr, src->arr, len * src->type); | |
return len; | |
} | |
int main() { | |
struct slice* s1 = make(sizeof(float), 5, 5); | |
float* arr = (float*)s1->arr; | |
arr[0] = -0xff; | |
arr[1] = -0xfe; | |
arr[2] = -0xfd; | |
arr[3] = -0xfc; | |
arr[4] = -0xfb; | |
float val = -0xfa; | |
float val2 = -0xf9; | |
s1 = append(2, s1, &val, &val2); | |
printf("s1: len: %d, cap: %d arr:\n", len(s1), cap(s1)); | |
for(int i = 0; i < len(s1); i++) { | |
printf("arr[%d]: %f\n", i, *((float*)s1->arr + i)); | |
} | |
struct slice* s2 = slice(s1, 2, 4); | |
printf("s2: len: %d, cap: %d arr:\n", len(s2), cap(s2)); | |
for(int i = 0; i < len(s2); i++) { | |
printf("arr[%d]: %f\n", i, *((float*)s2->arr + i)); | |
} | |
struct slice* s3 = make(sizeof(float), 5, 5); | |
s3->len = 5; | |
copy(s3, s1); | |
printf("s3: len: %d, cap: %d arr:\n", len(s3), cap(s3)); | |
for(int i = 0; i < len(s3); i++) { | |
printf("arr[%d]: %f\n", i, *((float*)s3->arr + i)); | |
} | |
return 0; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <stdlib.h> | |
template<typename T> | |
class slice { | |
int _len; | |
int _cap; | |
T* _arr; | |
public: | |
slice(int len) : slice(len,len) {} | |
slice(int len, int cap) { | |
_len = len; | |
_cap = cap; | |
_arr = (T*) calloc(cap, sizeof(T)); | |
} | |
~slice() { | |
free(_arr); | |
} | |
int len() { return _len; } | |
int cap() { return _cap; } | |
T& operator[](int i) { return _arr[i]; } | |
void append(T elem) { | |
if(_cap < _len+1) { | |
_arr = (T*) realloc(_arr, _len+1 * sizeof(T)); | |
_cap = _len+1; | |
} | |
_arr[_len++] = elem; | |
} | |
template<typename... Targs> | |
void append(T elem, Targs... args) { | |
append(elem); | |
append(args...); | |
} | |
slice<T> sslice(int start, int end) { | |
int len = end-start; | |
slice<T> s2(0, len); | |
for(int i = 0; i < len; i++) { | |
s2.append(_arr[start + i]); | |
} | |
return s2; | |
} | |
}; | |
int main() { | |
{ | |
slice<float> s0(3); | |
s0[0] = 3.f; | |
s0[1] = 0.1f; | |
s0[2] = 0.04f; | |
std::cout << "s0: len: " << s0.len(); | |
std::cout << " cap: " << s0.cap() << "\n"; | |
for(int i = 0; i < s0.len(); i++) { | |
std::cout << "arr[" << i << "]: " << s0[i] << "\n"; | |
} | |
} | |
slice<int> s1(0, 5); | |
s1.append(0xff,0xfe,0xfd,0xfc,0xfb,0xfa); | |
s1[2] = 0xcc; | |
std::cout << "s1: len: " << s1.len(); | |
std::cout << " cap: " << s1.cap() << "\n"; | |
for(int i = 0; i < s1.len(); i++) { | |
std::cout << "arr[" << i << "]: " << s1[i] << "\n"; | |
} | |
slice<int> s2 = s1.sslice(2, 4); | |
std::cout << "s2: len: " << s2.len(); | |
std::cout << " cap: " << s2.cap() << "\n"; | |
for(int i = 0; i < s2.len(); i++) { | |
std::cout << "arr[" << i << "]: " << s2[i] << "\n"; | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment