JeVois
1.22
JeVois Smart Embedded Machine Vision Toolkit
|
|
Source code line length is 120. Add this to your ~/.emacs to set it:
;; set default line wrap len: (setq default-fill-column 120)
~/
.emacs to activate): ;; JeVois indentation style for C++ and such (defun my-c-mode-common-hook () (local-set-key "\C-h" 'backward-delete-char) ;; this will make sure spaces are used instead of tabs (setq tab-width 4 indent-tabs-mode nil) (setq indent-tabs-mode 'nil) (setq c-basic-offset 2) (c-set-offset 'substatement-open 0) (c-set-offset 'statement-case-open 0) (c-set-offset 'case-label 0) (c-set-offset 'brace-list-open 0) (c-set-offset 'access-label -2) (c-set-offset 'inclass 4) (c-set-offset 'member-init-intro 4) ;; include possible ! as comment start string so that indentation starts after it (setq comment-start-skip "/\\*+!* *\\|//+ *") ;; type C-c C-s or C-c C-o while editing to see what other rules to add here... ) (add-hook 'c-mode-hook 'my-c-mode-common-hook) (add-hook 'c++-mode-hook 'my-c-mode-common-hook) (add-hook 'perl-mode-hook 'my-c-mode-common-hook) (add-hook 'cperl-mode-hook 'my-c-mode-common-hook) (add-hook 'emacs-lisp-mode-hook 'my-c-mode-common-hook) (add-hook 'nroff-mode-hook 'my-c-mode-common-hook) (add-hook 'tcl-mode-hook 'my-c-mode-common-hook) (add-hook 'makefile-mode-hook 'my-c-mode-common-hook)
"-------------Essential JeVois Style Compliance Settings------------- " Disable old-school vi compatability set nocompatible " Allow plugins to control our indentation filetype plugin indent on " Set each auto-indent level to equal two spaces set shiftwidth=2 " Let each tab equal two spaces set tabstop=2 " Make sure vim turns all tabs into spaces set expandtab " Make vim indent our code properly set smartindent " Make the maximum line length equal 120 set textwidth=120 "-------------Other cool vim tricks------------- " Use a cool menu when autocompleting filenames, commands, etc... set wildmenu set wildmode=list:longest " Make vim automatically change directories to the directory of any file you open. " This means that when you open a file, then want to open another using :tabe, :o, etc, " you can just type in the relative path from the file you're currently editing. set autochdir " When editing the JeVois library, it is a total pain when you are editing a .H file in jevois/include/whatever/whatever, " and then decide you need to edit the source .C file in the jevois/src/whatever/whatever. This little function will " automatically back track in the directory tree for you, find the corresponding .C or .H file, and open it in a new " tab. " To use it, just type ,o (that's a comma, and then a lower-case o). function! OpenOther() if expand("%:e") == "C" exe "tabe" fnameescape(expand("%:p:r:s?src?include?").".H") elseif expand("%:e") == "H" exe "tabe" fnameescape(expand("%:p:r:s?include?src?").".C") endif endfunction nmap ,o :call OpenOther()<CR>
details
subdirectory. In general, such backend functionality can be split into a Helpers file which contains any helper classes and can be included before the body of a class definition, and a Impl implementation file which includes any inline code. For example, the Parameter framework involves the main definitions and programming interface in jevois/include/jevois/Component/Parameter.H, which relies on some helper classes (which programmers using Parameter do not need to knwo about) defined in jevois/include/jevois/Component/details/ParameterHelpers.H, and has some inline implementation code (which programmers using Parameter also do not need to know about) defined in jevois/include/jevois/Component/details/ParameterImpl.H. This organization makes it easy to generate user documentation that omits all of the nasty implementation details.All .H files use include guards, which will prevent the file from being included several times, thereby generating some errors about things being re-defined. No .C file uses include guards. We use a pragma supported by g++ for include guards:
A new class will hence typically involve the following set of files:
include/jevois/XXX/MyClass.H
: only contains declarations and documentation. Absolutely no actual implementation code. Only declare in this file things of interest to programmers who will use your class and who do not need to care about exactly how it works internally. Everything in this file should be documented using doxygen markup.include/jevois/XXX/details/MyClassHelpers.H
: contains supporting declarations that must be known before the main declarations in MyClass.H can take effect. For example, if the end user will only use a derived class and the base class contains no information that they should care about, declare the base class in details/MyClassHelpers.H and towards the top of MyClass.H include details/MyClassHelpers.H. There is no doxygen markup in this file, and documentation is optional, mainly geared towards advanced programmers.include/jevois/XXX/details/MyClassImpl.H
: contains inlined and template implementation ONLY. There is no doxygen markup in this file, and documentation is optional, mainly geared towards advanced programmers.src/jevois/XXX/MyClass.C
: contains all non-template, non-inline implementation. Documentation is optional.See for example the following files:
~/.bash_aliases
or ~/.bashrc
: # do a grep on c sources (e.g., for kernel, u-boot, etc) or c++ sources (for JeVois, NRT, etc) xg () { grep $* `find . -name "*.[hcHC]"` }
You can use it as follows, for example to find all files that refer to the function warnAndRethrowException()
provided by JeVois to help programmers with handling of exceptions:
itti@iLab1:~/jevois/software/jevois$ xg warnAndRethrowException ./include/jevois/Debug/Log.H: try { do_something_risky(); } catch (...) { jevois::warnAndRethrowException(); } ./include/jevois/Debug/Log.H: void warnAndRethrowException[[noreturn]](); ./src/jevois/Debug/Log.C:void jevois::warnAndRethrowException()
Reveals that it is declared in Log.H and implemented in Log.C, so you can now open those files for more information.
JeVois uses exclusively the right-to-left convention for const qualifications. This is because it is the best way to unambiguously read statements that have const in them, just read them aloud from right to left. For example:
See http://en.wikipedia.org/wiki/Const-correctness for more details and examples. Also see this one: http://www.dansaks.com/articles/1999-02%20const%20T%20vs%20T%20const.pdf and that one: http://www.parashift.com/c++-faq-lite/const-correctness.html
mutable
, which will allow it to be locked/unlocked on const instances of the class or in const member functions of the class.const_cast
inside the function. For example, consider the implementation of the className() accessor function in Component, which returns the name of the component's class. itsClassName is declared in Component.H as a const string data member of Component, which makes sense since the class name cannot be modified for any Component. As for all const data members, the only way to assign a value to itsClassName is hence during construction. But we would like to report the class name of any class derived from Component, which is not accessible during construction of the base Component class. For this reason, we will set the class name the first time it is requested (at which point we know the object derived from Component will be fully constructed): const_cast
to set the const member variable itsClassName the first time it is requested.Example:
Class names should be written in CamelCase starting with an uppercase character, for example:
Member variables should be camelCase starting with the prefix “its”, for example:
Function names should be camelCase starting with a lowercase character, for example:
Typedef's which are just simple aliases for types should be CamelCase starting with an uppercase character, for example:
Anything that is the result of any fancy metaprogramming (e.g. static const variables or typedefs set by compile-time checks) should be written in all lowercase with underscores separating the words, for example: