Recent Entries 10
- pattern minor 112d agoAn optional_ref<T>I omitted all free operators but the equality comparisons ones because of verbosity. I am glad about any comments and improvements. Motivation I know that optional references are equivalent to pointers and their implementation is just such a wrapper. But I believe they make sense in some circumstances and please correct me if I am wrong. While implementing and using my interval map I needed to return an optional reference in one of its accessor methods, namely `operator[](Key)`. The idea is to get a reference to a stored value or nothing. Thus I did it there with an `std::optional>`. Following this pattern of optional refs led to complications when I tried accessing an `std::optional>` at some other point of time. I couldn't write something like this ``` int a = 0; std::optional> opt{a}; *opt = 42; assert(a == 42); ``` but instead one has to explicitly unwrap the `reference_wrapper` like this ``` opt.value().get() = 42; assert(a == 42); ``` or ``` opt->get() = 42 assert(a == 42); ``` And my motivation for `optional_ref` was born. Source code Here is the complete source code on wandbox. `optional_ref.hpp` ``` #include #include #include #include "range/v3/utility/concepts.hpp" namespace fub { struct bad_optional_access : std::runtime_error { using runtime_error::runtime_error; }; template class optional_ref { public: using element_type = T; using reference = element_type&; using pointer = element_type*; // CONSTRUCTORS optional_ref() = default; template ())> constexpr optional_ref(const optional_ref& other) noexcept : m_pointer{other.get_pointer()} {} constexpr optional_ref(reference element) noexcept : m_pointer{std::addressof(element)} {} // ASSIGNMENT template ())> constexpr optional_ref& operator=(const optional_ref& other) noexcept { m_pointer = other.get_pointer(); } // DESTRUCTOR ~optional_ref() = default; // SWAP
- pattern minor 112d agoC++: Smart Pointer ImplementationPlease could somebody verify that my method of implementing Smart Pointer is correct, and if there is maybe a more efficient way of achieving it. ``` #ifndef SHARED_PTR #define SHARED_PTR #include #include using namespace std; template class RCObject { T* rawObj; unsigned int count; mutex m_Mutx; public: RCObject() :rawObj(nullptr), count(0){} ~RCObject() { deref(); } RCObject(T* _rawObj):rawObj(_rawObj) { count = 0; } int getCount() const { return count; } T* get() { if (rawObj != nullptr) { return rawObj; } return nullptr; } void ref() { m_Mutx.lock(); count++; m_Mutx.unlock(); } void deref() { m_Mutx.lock(); count--; m_Mutx.unlock(); if (count == 0) { delete rawObj; count = 0; } } }; template class SharedPtr { RCObject* m_Rc; public: SharedPtr(T* rawObj) { m_Rc = new RCObject(rawObj); m_Rc->ref(); } ~SharedPtr() { m_Rc->deref(); } SharedPtr() { m_Rc = new RCObject(); } SharedPtr(const SharedPtr& rhs) { m_Rc = rhs.m_Rc; m_Rc->ref(); } SharedPtr& operator= (const SharedPtr& rhs) { if (this != &rhs) { m_Rc->deref(); m_Rc = rhs.m_Rc; m_Rc->ref(); } return *this; } int getRefCount() { return m_Rc->getCount(); } T* get() const { return m_Rc->get(); } T* operator->() { return m_Rc->get(); } }; #endif ```
- pattern minor 112d agoEnumerating an alphabetSince train rides can be long and boring, I've decided to make use of that time and fiddle around with some good ol' C. What I did was to create a way to enumerate words of a certain length of an arbitrary alphabet. Basically, suppose you have an alphabet ``` { '0', '1' } ``` (ooh, binary!) and want to get all words of length 7, you'd call ``` enumerate("01", 7); ``` and have a nice array of pointers containing the strings "0000000" to "1111111". What for, you ask? Dunno. Stuff. I've written it on my phone, so it may be a tad slimmer than the usual 80 characters. It's also not split into files for the very same reason. ``` #include #include #include #include #include char *translate( unsigned long value, const char *alphabet, size_t length ) { size_t base; char *result; if (!alphabet || (base = strlen(alphabet)) = 0 && value > 0; --i) { unsigned long mod = value % base; result[i] = alphabet[mod]; value -= mod; value /= base; } return result; } char **enumerate( const char *alphabet, const size_t length ) { size_t base; if (!alphabet || (base = strlen(alphabet)) < 2) { return NULL; } if (length == 0) { return NULL; } unsigned long end = pow(base, length); char **array = malloc((end + 1) * sizeof(char*)); if (!array) { return NULL; } array[end] = NULL; for (int i = 0; i != end; ++i) { char *storage = malloc(length + 1); char *translated = translate(i, alphabet, length); if (!storage || !translated) { if (storage) { free(storage); } if (translated) { free(translated); } array[i] = NULL; goto error_cleanup; } strcpy(storage, translated); free(translated); array[i] = storage; } return array; error_cleanup: for (int i = 0; array[i] != NULL; ++i) { free(array[i]); } free(array); return NULL; } ``` Example usage; simply concatenate the listings. ``` int main(int argc, char *ar
- pattern minor 112d agoTest if a binary tree satisfies the BST propertyI implemented code logic provided in the EPI book to determine if a binary tree is a BST. There were two approaches, therefore I used polymorphism for the common parts. I'm also using templates. I would appreciate code review on my use of smart pointers? Anything that I should have been doing that I'm not. I did not defined any destructors, should I? ``` #include #include #include #include using namespace std; template class BinarySearchNode { public: unique_ptr> leftChild; unique_ptr> rightChild; BinarySearchNode(T pData) : data(pData), leftChild(nullptr), rightChild(nullptr) {} BinarySearchNode(T pData, unique_ptr> pLeft, unique_ptr> pRight) : data(pData),leftChild(move(pLeft)), rightChild(move(pRight)) {} T getData() const { return data; }; private: T data; }; template class BSTSolution { protected: virtual bool isBSTValid(unique_ptr> const &node,T min, T max) = 0; public: bool isBinaryTreeValidBinaryTree(unique_ptr> const &root){ if(root == nullptr) return false; return isBSTValid(root, numeric_limits::min(), numeric_limits::max()); } }; template class BSTRecursiveSolution : public BSTSolution { protected: bool isBSTValid(unique_ptr> const &node,T min, T max) { if(node == nullptr) { return true; }; if(node->getData() getData() > max) { return false; } if(!isBSTValid(node->leftChild, min, node->getData()) || !isBSTValid(node->rightChild, node->getData(), max)) { return false; } return true; } }; template class BFSSolution : public BSTSolution { struct QEntry { const unique_ptr>& node; T min; T max; }; protected: bool isBSTValid(unique_ptr> const &node,T min, T max) { queue tempQueue; tempQueue.emplace(QEntry{node,min,max}); while (!tempQueue.empty()) { auto const current = tempQueue.f
- pattern minor 112d agoLinked list, pointer practiceThe vast majority of my experience is in writing managed code. I'm putting myself through C++ boot camp right now and trying to really wrap my head around pointers and memory management in general. Right now I'm working out of Gayle Laakmann's Cracking the Coding Interview. I've used it before for other languages and am revisiting it for C++. Here, I'm mostly concerned about memory management, but would also like to hear about any other C++ faux pas that might make me look bad in a whiteboarding session. I'll be moving on to other data structures after this, but this is my springboard, so I want to adjust as early as possible to write good code. The exercises I did are outlined in in `main()` with their outputs. I think out of all of this, I'm most concerned about how I'm approaching `deleteDuplicateEntries` for exercise 2.1. Also, any positive comments about implementation would be much appreciated so I make sure I continue to do what's working well. ``` #include template class ListNode { public: ListNode(Type input): value(input), next(NULL) {} void setValue(Type input) { value = input; } Type getValue() { return value; } void setNext(ListNode *nextTarget) { if(nextTarget != NULL) { next = nextTarget; } } ListNode * getNext() { return next; } private: Type value; ListNode *next; }; // singly linked list template class List { public: List(Type value) { _head = new ListNode(value); _tail = _head; _size = 1; } ~List() { // second param deletes as it traverses traverseHeadToTail(false, true); } // inserts at the end of the list void append(Type value) { ListNode *newNode = new ListNode(value); _tail->setNext(newNode); _tail = newNode; _size++; // if this makes two items, point head to tail if(_size == 2) { _head->setNext(_tail); } }
- pattern minor 112d agoParsing HTTP Headers in C++I am building a web server from scratch and trying to make certain tasks faster by embedding C code into the mix for performance. Specifically I'm worried about how the `std::string` class with the `.find()` and other functions compare to straight pointer arithmetic. ``` #include #include #include std::map http_request; void parse_header( void * ); int main() { char * msg= "GET / HTTP/1.1\r\n" "Host: 192.241.213.46:6880\r\n" "Upgrade-Insecure-Requests: 1\r\n" "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n" "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/602.4.8 (KHTML, like Gecko) Version/10.0.3 Safari/602.4.8\r\n" "Accept-Language: en-us\r\n" "Accept-Encoding: gzip, deflate\r\n" "Connection: keep-alive\r\n\r\n"; parse_header( msg ); } void parse_header( void *msg ) { char *head = (char *) msg; char *mid; char *tail = head; if( sizeof( msg ) == 0 ) { return; } // Find request type while( *head++ != ' '); http_request[ "Type" ] = std::string( ( char * ) msg ).substr( 0 , ( head - 1) - tail ); // Find path tail = head; while( *head++ != ' '); http_request[ "Path" ] = std::string( ( char * ) msg ).substr( tail - ( char *)msg , ( head - 1) - tail ); // Find HTTP version tail = head; while( *head++ != '\r'); http_request[ "Version" ] = std::string( ( char * ) msg ).substr( tail - ( char *)msg , ( head - 1) - tail ); // Map all headers from a key to a value while( true ) { tail = head + 1; while( *head++ != '\r' ); mid = strstr( tail, ":" ); // Look for the failed strstr if( tail > mid ) break; http_request[ std::string( ( char * ) msg ).substr( tail - ( char *)msg , ( mid ) - tail ) ] = std::string( ( char * ) msg ).substr( mid +
- pattern minor 112d agoCommand manipulation functions for a toy shell programI am writing a small program that is supposed to act as a shell of some sorts. It operates off of a few basic structures, one of them being a `command`, a `command_list`, and a `command_history`. ``` typedef struct command command; typedef struct { char** list; int len; } command_history; typedef struct { command** list; int len; command_history* history; } command_list; typedef struct command { char* alias; void (*function)(command_list*); } command; ``` I have written functions to add new commands, add new history, find aliases in a list and return its index, among other things, but I have a feeling that the command for adding commands, `addcommand` is leaking memory. I am not very experienced with C and this is just an experiment to acquaint me with pointers. I would appreciate some feedback on the code I have written and how I can improve it. Command manipulation functions: ``` void addcommand(char* str, void* fun, command_list* srclist) { printdebug("Adding command \"%s\" pointing to function at %p in command list located at %p... ", str, fun, srclist); srclist -> list = realloc(srclist -> list, sizeof(command*) * (srclist -> len + 1)); srclist -> list[srclist -> len] = malloc(sizeof(command)); srclist -> list[srclist -> len] -> alias = malloc(sizeof(char) * (strlen(str) + 1)); srclist -> list[srclist -> len] -> function = malloc(sizeof(void*)); // problems here and | memcpy(srclist -> list[srclist -> len] -> alias, str, sizeof(char) * (strlen(str) + 1)); // | srclist -> list[srclist -> len] -> function = fun; // len++; printdebug("Command added.\n"); } void addhistory(char* str, command_list* srclist) { printdebug("Adding \"%s\" to history list located at %p...", str, srclist -> history); srclist -> history -> list = realloc(srclist -> history -> list, sizeof(char*) * (srclist -> history -> len + 1)); srclist -> history -> list[srclist ->
- pattern minor 112d agoImplementing a shared_ptr class in C++I'm trying to write my own shared_ptr/weak_ptr implementation in C++. I have the following requirements: I do NOT need support for the following: - multithreading (synchronisation) - support for polymorphic types as the templated type of the shared_ptr (such as shared_ptr Base*) Reasons for wanting to write my own implementation: - need to supply a separate allocator for the control block - need to reduce the size of the control block (the standard version has a very large control block due to its support for multithreading and polymorphism among other things) Concerns: - I'm worried about using my current implementation in production code (need some suggestions on how best to thoroughly test it) - I'm concerned I may have left out important features from my implementation The following is what I've written so far (compilable in a C++11 compliant compiler, with main function and example): ``` #include #include struct shared_ptr_control_base { virtual ~shared_ptr_control_base() { } void decrement_count_shared() noexcept { m_shared--; } void increment_count_shared() noexcept { m_shared++; } void decrement_count_weak() noexcept { m_weak--; } void increment_count_weak() noexcept { m_weak++; } virtual void destroy_shared(void*) noexcept = 0; virtual void destruct() noexcept = 0; virtual shared_ptr_control_base* create() const = 0; uint32_t m_shared = 1; uint32_t m_weak = 0; }; template struct shared_ptr_control_derived : shared_ptr_control_base { shared_ptr_control_derived() = delete; shared_ptr_control_derived(AllocatorType a_allocator) : m_allocator(a_allocator) { } shared_ptr_control_derived* create() const { auto l_alloctor = std::allocator>(); auto l_p = l_alloctor.allocate(1); l_alloctor.construct(l_p, *this); return l_p; } void destroy_shared(void* a_pointer) noe
- pattern minor 112d agoC++ Linked list with smart pointersThis seems to work fine, but I'm very new to C++ and would like any suggestions for improvements. Areas I have the most trouble with are: - Namespacing (honestly, it's still half looking stuff up and making an educated guess with typename blah blah blah). Is there a "cleaner" way to implement this? - Various C++ idioms (copy and swap) that aren't as common in, say, C or Java. There are good answers relating to copy and swap in particular, but I just don't quite "get it" yet. The principal makes sense, but specifically what to do with regards to protecting against exceptions in the copy constructor itself - Adding to that, exceptions in general in C++ (coming from the strict Java approach and the "check errno/return value/whatever" C approach), although in the context of this code it's more about guaranteeing exception safety where people would expect it (see above). - General good "style". Specifically, what's the cleanest way to implement the `Node` class in data structures where we see something like this? this plays into how namespacing can get tricky. There seems to be a tradeoff of encapsulation (e.g. defining a struct node within the LinkedList class seems intuitively more "reasonable", but this makes dealing with nodes in any function that may be written outside my definition file strewn with typename). - Another example: should `root` really be a `unique_ptr` here instead of a regular object? It certainly made my code easier to write, but I'm curious as to arguments for or against it. - I'm still fairly unclear as to when exactly I need the template declaration for classes (see the copy constructor for instance, where it takes `LinkedList` as an argument instead of `LinkedList`, but it worked, which seems odd). I understand the use case between e.g. unique_ptr and shared_ptr for the most part, but certainly want to know if I'm misusing anything here. There is nothing fancy (like a reference to the tail to make insertion faster), but I just want
- pattern minor 112d agoC++ maybe pointer type implementationMotivation This is intended to implement a C++ `maybe_ptr` type that can either hold a pointer to an underlying type `T` or a `nullptr`. The idea is to guarantee at compile-time the absence of null pointer dereferencing errors in code that uses raw pointers. Traditionally, these kinds of errors are prevented by the user having to guard pointer dereferencing by explicitly checking `nullptr`. For example: ``` void foo(int* n) { if(n != nullptr) { bar(*n); } } ``` The obvious danger is that the user forgets to check for `nullptr`, in which case it is undefined behavior that is not detected by the compiler and may not even be easily detected at run-time. In contrast, `maybe_ptr` guarantees `nullptr` checking before the user is able to deference the raw pointer. Usage Before getting to the implementation, let's see how `maybe_ptr` is used (leveraging C++11 lambdas): ``` void foo(const maybe_ptr& ptr) { bool ran = maybe_if(ptr, [](int* n) { bar(*n); // never reached if n is null }); // ran is true if ptr did not contain null (i.e. the lambda was run) } ``` We can easily assign raw pointers to initialize `maybe_ptr`: ``` int n; maybe_ptr ptr = &n; ``` Note that `maybe_ptr` does not allow any direct access to the raw pointer once it is assigned: ``` maybe_ptr ptr; std::string* s = *ptr; // compiler error: no "*" operator defined ptr->length(); // compiler error: no "->" operator defined ptr->get(); // compiler error: "get" is inaccessible (private method) ``` The only way to access the pointer is through the `maybe_if` function, with a function pointer, lambda function, or functor. A couple overloaded `maybe_if` functions are provided for convenient, simultaneous access to multiple pointers within the same lambda function: ``` void foo(const maybe_ptr& ptr1, const maybe_ptr& ptr2) { bool ran = maybe_if(ptr1, ptr2, [](int* n, float* x) { bar(*n, *x); // never reached if n or x are null });